mercurial/scmutil.py
author Siddharth Agarwal <sid0@fb.com>
Fri, 18 Jan 2013 15:55:16 -0800
changeset 18442 ecba9b0e7672
parent 18327 4aecdb91443c
child 18450 4f9a52858512
permissions -rw-r--r--
posix: don't compare atime when determining if a file has changed A file's atime might change even if the file itself doesn't change. This might cause us to invalidate caches more often than necessary. Before this change, hg add often resulted in the dirstate being parsed twice on systems that track atime. After this change, it is only parsed once. For a repository with over 180,000 files, this speeds up hg add from 1.2 seconds to 1.0.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     1
# scmutil.py - Mercurial core utility functions
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     2
#
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     3
#  Copyright Matt Mackall <mpm@selenic.com>
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     4
#
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     7
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     8
from i18n import _
17248
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
     9
import util, error, osutil, revset, similar, encoding, phases
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
    10
import match as matchmod
14861
6ed2a449cb5b scmutil: add missing import of re
Steve Borho <steve@borho.org>
parents: 14746
diff changeset
    11
import os, errno, re, stat, sys, glob
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    12
17248
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    13
def nochangesfound(ui, repo, excluded=None):
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    14
    '''Report no changes for push/pull, excluded is None or a list of
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    15
    nodes excluded from the push/pull.
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    16
    '''
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    17
    secretlist = []
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    18
    if excluded:
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    19
        for n in excluded:
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    20
            ctx = repo[n]
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    21
            if ctx.phase() >= phases.secret and not ctx.extinct():
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    22
                secretlist.append(n)
6ffb35b2284c discovery: add extinct changesets to outgoing.excluded
Patrick Mezard <patrick@mezard.eu>
parents: 17201
diff changeset
    23
15993
0b05e0bfdc1c scmutil: unify some 'no changes found' messages
Matt Mackall <mpm@selenic.com>
parents: 15797
diff changeset
    24
    if secretlist:
0b05e0bfdc1c scmutil: unify some 'no changes found' messages
Matt Mackall <mpm@selenic.com>
parents: 15797
diff changeset
    25
        ui.status(_("no changes found (ignored %d secret changesets)\n")
0b05e0bfdc1c scmutil: unify some 'no changes found' messages
Matt Mackall <mpm@selenic.com>
parents: 15797
diff changeset
    26
                  % len(secretlist))
0b05e0bfdc1c scmutil: unify some 'no changes found' messages
Matt Mackall <mpm@selenic.com>
parents: 15797
diff changeset
    27
    else:
0b05e0bfdc1c scmutil: unify some 'no changes found' messages
Matt Mackall <mpm@selenic.com>
parents: 15797
diff changeset
    28
        ui.status(_("no changes found\n"))
0b05e0bfdc1c scmutil: unify some 'no changes found' messages
Matt Mackall <mpm@selenic.com>
parents: 15797
diff changeset
    29
17821
361ab1e2086f scmutil: add bad character checking to checknewlabel
Kevin Bullock <kbullock@ringworld.org>
parents: 17817
diff changeset
    30
def checknewlabel(repo, lbl, kind):
17817
b17be267b59c scmutil: add function to validate new branch, tag, and bookmark names
Kevin Bullock <kbullock@ringworld.org>
parents: 17768
diff changeset
    31
    if lbl in ['tip', '.', 'null']:
b17be267b59c scmutil: add function to validate new branch, tag, and bookmark names
Kevin Bullock <kbullock@ringworld.org>
parents: 17768
diff changeset
    32
        raise util.Abort(_("the name '%s' is reserved") % lbl)
17821
361ab1e2086f scmutil: add bad character checking to checknewlabel
Kevin Bullock <kbullock@ringworld.org>
parents: 17817
diff changeset
    33
    for c in (':', '\0', '\n', '\r'):
361ab1e2086f scmutil: add bad character checking to checknewlabel
Kevin Bullock <kbullock@ringworld.org>
parents: 17817
diff changeset
    34
        if c in lbl:
17850
71c1513fd560 scmutil: generalize message to make it more i18n-friendly
Wagner Bruna <wbruna@yahoo.com>
parents: 17846
diff changeset
    35
            raise util.Abort(_("%r cannot be used in a name") % c)
17817
b17be267b59c scmutil: add function to validate new branch, tag, and bookmark names
Kevin Bullock <kbullock@ringworld.org>
parents: 17768
diff changeset
    36
13974
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
    37
def checkfilename(f):
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
    38
    '''Check that the filename f is an acceptable filename for a tracked file'''
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
    39
    if '\r' in f or '\n' in f:
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
    40
        raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") % f)
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
    41
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    42
def checkportable(ui, f):
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    43
    '''Check if filename f is portable and warn or abort depending on config'''
13974
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
    44
    checkfilename(f)
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    45
    abort, warn = checkportabilityalert(ui)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    46
    if abort or warn:
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    47
        msg = util.checkwinfilename(f)
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    48
        if msg:
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    49
            msg = "%s: %r" % (msg, f)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    50
            if abort:
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    51
                raise util.Abort(msg)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    52
            ui.warn(_("warning: %s\n") % msg)
14068
04ce8fa1015d add: notify when adding a file that would cause a case-folding collision
Kevin Gessner <kevin@kevingessner.com>
parents: 14067
diff changeset
    53
14067
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    54
def checkportabilityalert(ui):
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    55
    '''check if the user's config requests nothing, a warning, or abort for
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    56
    non-portable filenames'''
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    57
    val = ui.config('ui', 'portablefilenames', 'warn')
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    58
    lval = val.lower()
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    59
    bval = util.parsebool(val)
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    60
    abort = os.name == 'nt' or lval == 'abort'
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    61
    warn = bval or lval == 'warn'
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    62
    if bval is None and not (warn or abort or lval == 'ignore'):
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    63
        raise error.ConfigError(
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
    64
            _("ui.portablefilenames value is invalid ('%s')") % val)
14067
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    65
    return abort, warn
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    66
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    67
class casecollisionauditor(object):
17201
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    68
    def __init__(self, ui, abort, dirstate):
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    69
        self._ui = ui
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    70
        self._abort = abort
17201
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    71
        allfiles = '\0'.join(dirstate._map)
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    72
        self._loweredfiles = set(encoding.lower(allfiles).split('\0'))
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    73
        self._dirstate = dirstate
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    74
        # The purpose of _newfiles is so that we don't complain about
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    75
        # case collisions if someone were to call this object with the
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    76
        # same filename twice.
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    77
        self._newfiles = set()
14067
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
    78
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    79
    def __call__(self, f):
14980
28e98a8b173d i18n: use UTF-8 string to lower filename for case collision check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14861
diff changeset
    80
        fl = encoding.lower(f)
17201
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    81
        if (fl in self._loweredfiles and f not in self._dirstate and
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    82
            f not in self._newfiles):
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    83
            msg = _('possible case-folding collision for %s') % f
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    84
            if self._abort:
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    85
                raise util.Abort(msg)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
    86
            self._ui.warn(_("warning: %s\n") % msg)
17201
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    87
        self._loweredfiles.add(fl)
afd75476939e scmutil: 25% speedup in casecollisionauditor
Joshua Redstone <joshua.redstone@fb.com>
parents: 17161
diff changeset
    88
        self._newfiles.add(f)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
    89
14220
21b8ce4d3331 rename path_auditor to pathauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14167
diff changeset
    90
class pathauditor(object):
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    91
    '''ensure that a filesystem path contains no banned components.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    92
    the following properties of a path are checked:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    93
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    94
    - ends with a directory separator
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    95
    - under top-level .hg
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    96
    - starts at the root of a windows drive
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    97
    - contains ".."
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    98
    - traverses a symlink (e.g. a/symlink_here/b)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
    99
    - inside a nested repository (a callback can be used to approve
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   100
      some nested repositories, e.g., subrepositories)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   101
    '''
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   102
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   103
    def __init__(self, root, callback=None):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   104
        self.audited = set()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   105
        self.auditeddir = set()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   106
        self.root = root
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   107
        self.callback = callback
15666
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
   108
        if os.path.lexists(root) and not util.checkcase(root):
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
   109
            self.normcase = util.normcase
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
   110
        else:
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
   111
            self.normcase = lambda x: x
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   112
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   113
    def __call__(self, path):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   114
        '''Check the relative path.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   115
        path may contain a pattern (e.g. foodir/**.txt)'''
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   116
15721
4751d5133f15 windows: force specified path to be audited in localpath form
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15666
diff changeset
   117
        path = util.localpath(path)
15666
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
   118
        normpath = self.normcase(path)
15664
ec8730886f36 pathauditor: use normcase()-ed path for audit result cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14984
diff changeset
   119
        if normpath in self.audited:
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   120
            return
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   121
        # AIX ignores "/" at end of path, others raise EISDIR.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   122
        if util.endswithsep(path):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   123
            raise util.Abort(_("path ends in directory separator: %s") % path)
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   124
        parts = util.splitpath(path)
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   125
        if (os.path.splitdrive(path)[0]
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   126
            or parts[0].lower() in ('.hg', '.hg.', '')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   127
            or os.pardir in parts):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   128
            raise util.Abort(_("path contains illegal component: %s") % path)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   129
        if '.hg' in path.lower():
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   130
            lparts = [p.lower() for p in parts]
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   131
            for p in '.hg', '.hg.':
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   132
                if p in lparts[1:]:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   133
                    pos = lparts.index(p)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   134
                    base = os.path.join(*parts[:pos])
15436
18f1bb70462e cmdutil: don't use repr on paths in pathauditor - it looks strange on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 14984
diff changeset
   135
                    raise util.Abort(_("path '%s' is inside nested repo %r")
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   136
                                     % (path, base))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   137
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   138
        normparts = util.splitpath(normpath)
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   139
        assert len(parts) == len(normparts)
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   140
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   141
        parts.pop()
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   142
        normparts.pop()
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   143
        prefixes = []
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   144
        while parts:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   145
            prefix = os.sep.join(parts)
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   146
            normprefix = os.sep.join(normparts)
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   147
            if normprefix in self.auditeddir:
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   148
                break
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   149
            curpath = os.path.join(self.root, prefix)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   150
            try:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   151
                st = os.lstat(curpath)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   152
            except OSError, err:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   153
                # EINVAL can be raised as invalid path syntax under win32.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   154
                # They must be ignored for patterns can be checked too.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   155
                if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   156
                    raise
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   157
            else:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   158
                if stat.S_ISLNK(st.st_mode):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   159
                    raise util.Abort(
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   160
                        _('path %r traverses symbolic link %r')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   161
                        % (path, prefix))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   162
                elif (stat.S_ISDIR(st.st_mode) and
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   163
                      os.path.isdir(os.path.join(curpath, '.hg'))):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   164
                    if not self.callback or not self.callback(curpath):
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   165
                        raise util.Abort(_("path '%s' is inside nested "
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   166
                                           "repo %r")
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   167
                                         % (path, prefix))
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   168
            prefixes.append(normprefix)
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   169
            parts.pop()
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
   170
            normparts.pop()
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   171
15664
ec8730886f36 pathauditor: use normcase()-ed path for audit result cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14984
diff changeset
   172
        self.audited.add(normpath)
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   173
        # only add prefixes to the cache after checking everything: we don't
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   174
        # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   175
        self.auditeddir.update(prefixes)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
   176
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   177
class abstractvfs(object):
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
   178
    """Abstract base class; cannot be instantiated"""
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
   179
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
   180
    def __init__(self, *args, **kwargs):
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
   181
        '''Prevent instantiation; don't call this from subclasses.'''
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
   182
        raise NotImplementedError('attempted instantiating ' + str(type(self)))
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
   183
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   184
    def tryread(self, path):
16479
fc04698fa778 opener: coding style, use triple quotes for doc string
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16455
diff changeset
   185
        '''gracefully return an empty string for missing files'''
16455
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   186
        try:
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   187
            return self.read(path)
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   188
        except IOError, inst:
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   189
            if inst.errno != errno.ENOENT:
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   190
                raise
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   191
        return ""
154219f3a6a4 opener: introduce tryread helper
Matt Mackall <mpm@selenic.com>
parents: 16436
diff changeset
   192
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   193
    def read(self, path):
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   194
        fp = self(path, 'rb')
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   195
        try:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   196
            return fp.read()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   197
        finally:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   198
            fp.close()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   199
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   200
    def write(self, path, data):
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   201
        fp = self(path, 'wb')
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   202
        try:
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   203
            return fp.write(data)
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   204
        finally:
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   205
            fp.close()
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   206
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   207
    def append(self, path, data):
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
   208
        fp = self(path, 'ab')
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   209
        try:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   210
            return fp.write(data)
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   211
        finally:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   212
            fp.close()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
   213
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   214
    def exists(self, path=None):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   215
        return os.path.exists(self.join(path))
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   216
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   217
    def isdir(self, path=None):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   218
        return os.path.isdir(self.join(path))
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   219
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   220
    def makedir(self, path=None, notindexed=True):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   221
        return util.makedir(self.join(path), notindexed)
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   222
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   223
    def makedirs(self, path=None, mode=None):
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   224
        return util.makedirs(self.join(path), mode)
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   225
17723
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   226
    def mkdir(self, path=None):
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   227
        return os.mkdir(self.join(path))
ab23768746fd scmutil: reorder newly added functions for vfs support in dictionary order
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17681
diff changeset
   228
17747
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
   229
    def readdir(self, path=None, stat=None, skip=None):
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
   230
        return osutil.listdir(self.join(path), stat, skip)
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
   231
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   232
    def stat(self, path=None):
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   233
        return os.stat(self.join(path))
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   234
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   235
class vfs(abstractvfs):
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   236
    '''Operate files relative to a base directory
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   237
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   238
    This class is used to hide the details of COW semantics and
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   239
    remote file access from higher level code.
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   240
    '''
17157
87e8440964a0 localrepo: use path expansion API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17104
diff changeset
   241
    def __init__(self, base, audit=True, expand=False):
87e8440964a0 localrepo: use path expansion API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17104
diff changeset
   242
        if expand:
87e8440964a0 localrepo: use path expansion API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17104
diff changeset
   243
            base = os.path.realpath(util.expandpath(base))
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   244
        self.base = base
17554
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   245
        self._setmustaudit(audit)
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   246
        self.createmode = None
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   247
        self._trustnlink = None
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   248
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   249
    def _getmustaudit(self):
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   250
        return self._audit
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   251
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   252
    def _setmustaudit(self, onoff):
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   253
        self._audit = onoff
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   254
        if onoff:
18327
4aecdb91443c scmutil: simplify vfs.audit - drop wrapped vfs.auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18316
diff changeset
   255
            self.audit = pathauditor(self.base)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   256
        else:
18327
4aecdb91443c scmutil: simplify vfs.audit - drop wrapped vfs.auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18316
diff changeset
   257
            self.audit = util.always
17554
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   258
5450c8ad9d98 scmutil: turn opener._audit into a property, mustaudit
Bryan O'Sullivan <bryano@fb.com>
parents: 17248
diff changeset
   259
    mustaudit = property(_getmustaudit, _setmustaudit)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   260
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   261
    @util.propertycache
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
   262
    def _cansymlink(self):
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   263
        return util.checklink(self.base)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   264
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   265
    @util.propertycache
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   266
    def _chmod(self):
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   267
        return util.checkexec(self.base)
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   268
17763
13070de77c86 vfs: backout fchmod change from 76b73ce0ffac
Matt Mackall <mpm@selenic.com>
parents: 17752
diff changeset
   269
    def _fixfilemode(self, name):
18192
f9a89bdd64a6 scmutil: don't try to match modes on filesystems without modes (issue3740)
Matt Mackall <mpm@selenic.com>
parents: 17850
diff changeset
   270
        if self.createmode is None or not self._chmod:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   271
            return
17763
13070de77c86 vfs: backout fchmod change from 76b73ce0ffac
Matt Mackall <mpm@selenic.com>
parents: 17752
diff changeset
   272
        os.chmod(name, self.createmode & 0666)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   273
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   274
    def __call__(self, path, mode="r", text=False, atomictemp=False):
14720
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
   275
        if self._audit:
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
   276
            r = util.checkosfilename(path)
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
   277
            if r:
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
   278
                raise util.Abort("%s: %r" % (r, path))
18327
4aecdb91443c scmutil: simplify vfs.audit - drop wrapped vfs.auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18316
diff changeset
   279
        self.audit(path)
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   280
        f = self.join(path)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   281
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   282
        if not text and "b" not in mode:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   283
            mode += "b" # for that other OS
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   284
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   285
        nlink = -1
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   286
        if mode not in ('r', 'rb'):
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   287
            dirname, basename = util.split(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   288
            # If basename is empty, then the path is malformed because it points
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   289
            # to a directory. Let the posixfile() call below raise IOError.
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   290
            if basename:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   291
                if atomictemp:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   292
                    if not os.path.isdir(dirname):
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   293
                        util.makedirs(dirname, self.createmode)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   294
                    return util.atomictempfile(f, mode, self.createmode)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   295
                try:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   296
                    if 'w' in mode:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   297
                        util.unlink(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   298
                        nlink = 0
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   299
                    else:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   300
                        # nlinks() may behave differently for files on Windows
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   301
                        # shares if the file is open.
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   302
                        fd = util.posixfile(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   303
                        nlink = util.nlinks(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   304
                        if nlink < 1:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   305
                            nlink = 2 # force mktempcopy (issue1922)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   306
                        fd.close()
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   307
                except (OSError, IOError), e:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   308
                    if e.errno != errno.ENOENT:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   309
                        raise
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   310
                    nlink = 0
17937
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   311
                    if not os.path.isdir(dirname):
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   312
                        util.makedirs(dirname, self.createmode)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   313
                if nlink > 0:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   314
                    if self._trustnlink is None:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   315
                        self._trustnlink = nlink > 1 or util.checknlink(f)
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   316
                    if nlink > 1 or not self._trustnlink:
3cb032d50447 vfs: optimize __call__ by not calling util.split for reads
Adrian Buehlmann <adrian@cadifra.com>
parents: 17850
diff changeset
   317
                        util.rename(util.mktempcopy(f), f)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   318
        fp = util.posixfile(f, mode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   319
        if nlink == 0:
17763
13070de77c86 vfs: backout fchmod change from 76b73ce0ffac
Matt Mackall <mpm@selenic.com>
parents: 17752
diff changeset
   320
            self._fixfilemode(f)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   321
        return fp
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   322
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   323
    def symlink(self, src, dst):
18327
4aecdb91443c scmutil: simplify vfs.audit - drop wrapped vfs.auditor
Mads Kiilerich <mads@kiilerich.com>
parents: 18316
diff changeset
   324
        self.audit(dst)
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   325
        linkname = self.join(dst)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   326
        try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   327
            os.unlink(linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   328
        except OSError:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   329
            pass
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   330
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   331
        dirname = os.path.dirname(linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   332
        if not os.path.exists(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   333
            util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   334
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
   335
        if self._cansymlink:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   336
            try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   337
                os.symlink(src, linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   338
            except OSError, err:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   339
                raise OSError(err.errno, _('could not symlink to %r: %s') %
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   340
                              (src, err.strerror), linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
   341
        else:
17768
9837cafc25b1 vfs: use self.write to write symlink placeholders
Matt Mackall <mpm@selenic.com>
parents: 17763
diff changeset
   342
            self.write(dst, src)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   343
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   344
    def join(self, path):
17161
be016e96117a localrepo: use file API via vfs while ensuring repository directory
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17157
diff changeset
   345
        if path:
17681
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   346
            return os.path.join(self.base, path)
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   347
        else:
a41fd730f230 scmutil: backout 83785bb56062 (issue3643)
Matt Mackall <mpm@selenic.com>
parents: 17675
diff changeset
   348
            return self.base
16199
8181bd808dc5 scmutil: add join method to opener to construct path relative to base
Idan Kamara <idankk86@gmail.com>
parents: 16198
diff changeset
   349
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   350
opener = vfs
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   351
17845
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   352
class auditvfs(object):
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   353
    def __init__(self, vfs):
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   354
        self.vfs = vfs
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   355
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   356
    def _getmustaudit(self):
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   357
        return self.vfs.mustaudit
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   358
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   359
    def _setmustaudit(self, onoff):
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   360
        self.vfs.mustaudit = onoff
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   361
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   362
    mustaudit = property(_getmustaudit, _setmustaudit)
408ded42c5ec scmutil: abstract out mustaudit delegation
Bryan O'Sullivan <bryano@fb.com>
parents: 17821
diff changeset
   363
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   364
class filtervfs(abstractvfs, auditvfs):
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   365
    '''Wrapper vfs for filtering filenames with a function.'''
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   366
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   367
    def __init__(self, vfs, filter):
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   368
        auditvfs.__init__(self, vfs)
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   369
        self._filter = filter
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   370
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   371
    def __call__(self, path, *args, **kwargs):
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   372
        return self.vfs(self._filter(path), *args, **kwargs)
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
   373
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   374
    def join(self, path):
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   375
        if path:
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   376
            return self.vfs.join(self._filter(path))
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   377
        else:
17846
f42cf30873dc scmutil: add mustaudit delegation to filtervfs (issue3673)
Bryan O'Sullivan <bryano@fb.com>
parents: 17845
diff changeset
   378
            return self.vfs.join(path)
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17723
diff changeset
   379
17649
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   380
filteropener = filtervfs
f65c6a5f256c scmutil: rename classes from "opener" to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17561
diff changeset
   381
18213
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   382
class readonlyvfs(abstractvfs, auditvfs):
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   383
    '''Wrapper vfs preventing any writing.'''
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   384
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   385
    def __init__(self, vfs):
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   386
        auditvfs.__init__(self, vfs)
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   387
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   388
    def __call__(self, path, mode='r', *args, **kw):
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   389
        if mode not in ('r', 'rb'):
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   390
            raise util.Abort('this vfs is read only')
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   391
        return self.vfs(path, mode, *args, **kw)
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   392
c38a62af000e vfs: add a read only vfs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18206
diff changeset
   393
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   394
def canonpath(root, cwd, myname, auditor=None):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   395
    '''return the canonical path of myname, given cwd and root'''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   396
    if util.endswithsep(root):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   397
        rootsep = root
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   398
    else:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   399
        rootsep = root + os.sep
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   400
    name = myname
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   401
    if not os.path.isabs(name):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   402
        name = os.path.join(root, cwd, name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   403
    name = os.path.normpath(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   404
    if auditor is None:
14220
21b8ce4d3331 rename path_auditor to pathauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14167
diff changeset
   405
        auditor = pathauditor(root)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   406
    if name != rootsep and name.startswith(rootsep):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   407
        name = name[len(rootsep):]
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   408
        auditor(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   409
        return util.pconvert(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   410
    elif name == root:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   411
        return ''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   412
    else:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   413
        # Determine whether `name' is in the hierarchy at or beneath `root',
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   414
        # by iterating name=dirname(name) until that causes no change (can't
17007
21e18c608b68 scmutil: change canonpath to use util.samefile (issue2167)
Adrian Buehlmann <adrian@cadifra.com>
parents: 16828
diff changeset
   415
        # check name == '/', because that doesn't work on windows). The list
21e18c608b68 scmutil: change canonpath to use util.samefile (issue2167)
Adrian Buehlmann <adrian@cadifra.com>
parents: 16828
diff changeset
   416
        # `rel' holds the reversed list of components making up the relative
21e18c608b68 scmutil: change canonpath to use util.samefile (issue2167)
Adrian Buehlmann <adrian@cadifra.com>
parents: 16828
diff changeset
   417
        # file name we want.
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   418
        rel = []
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   419
        while True:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   420
            try:
17007
21e18c608b68 scmutil: change canonpath to use util.samefile (issue2167)
Adrian Buehlmann <adrian@cadifra.com>
parents: 16828
diff changeset
   421
                s = util.samefile(name, root)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   422
            except OSError:
17007
21e18c608b68 scmutil: change canonpath to use util.samefile (issue2167)
Adrian Buehlmann <adrian@cadifra.com>
parents: 16828
diff changeset
   423
                s = False
21e18c608b68 scmutil: change canonpath to use util.samefile (issue2167)
Adrian Buehlmann <adrian@cadifra.com>
parents: 16828
diff changeset
   424
            if s:
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   425
                if not rel:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   426
                    # name was actually the same as root (maybe a symlink)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   427
                    return ''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   428
                rel.reverse()
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   429
                name = os.path.join(*rel)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   430
                auditor(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   431
                return util.pconvert(name)
17561
4647aa33ad81 scmutil: use the new faster path split
Bryan O'Sullivan <bryano@fb.com>
parents: 17559
diff changeset
   432
            dirname, basename = util.split(name)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   433
            rel.append(basename)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   434
            if dirname == name:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   435
                break
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   436
            name = dirname
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   437
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
   438
        raise util.Abort('%s not under root' % myname)
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   439
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   440
def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
17104
5a9acb0b2086 help: improve hgweb help
Mads Kiilerich <mads@kiilerich.com>
parents: 17037
diff changeset
   441
    '''yield every hg repository under path, always recursively.
5a9acb0b2086 help: improve hgweb help
Mads Kiilerich <mads@kiilerich.com>
parents: 17037
diff changeset
   442
    The recurse flag will only control recursion into repo working dirs'''
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   443
    def errhandler(err):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   444
        if err.filename == path:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   445
            raise err
14961
5523529bd1af walkrepos: use getattr instead of hasattr for samestat
Augie Fackler <durin42@gmail.com>
parents: 14928
diff changeset
   446
    samestat = getattr(os.path, 'samestat', None)
5523529bd1af walkrepos: use getattr instead of hasattr for samestat
Augie Fackler <durin42@gmail.com>
parents: 14928
diff changeset
   447
    if followsym and samestat is not None:
14227
94985b5a8278 scmutil: rename local function _add_dir_if_not_there
Adrian Buehlmann <adrian@cadifra.com>
parents: 14226
diff changeset
   448
        def adddir(dirlst, dirname):
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   449
            match = False
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   450
            dirstat = os.stat(dirname)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   451
            for lstdirstat in dirlst:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   452
                if samestat(dirstat, lstdirstat):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   453
                    match = True
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   454
                    break
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   455
            if not match:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   456
                dirlst.append(dirstat)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   457
            return not match
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   458
    else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   459
        followsym = False
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   460
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   461
    if (seen_dirs is None) and followsym:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   462
        seen_dirs = []
14227
94985b5a8278 scmutil: rename local function _add_dir_if_not_there
Adrian Buehlmann <adrian@cadifra.com>
parents: 14226
diff changeset
   463
        adddir(seen_dirs, path)
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   464
    for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   465
        dirs.sort()
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   466
        if '.hg' in dirs:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   467
            yield root # found a repository
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   468
            qroot = os.path.join(root, '.hg', 'patches')
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   469
            if os.path.isdir(os.path.join(qroot, '.hg')):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   470
                yield qroot # we have a patch queue repo here
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   471
            if recurse:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   472
                # avoid recursing inside the .hg directory
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   473
                dirs.remove('.hg')
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   474
            else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   475
                dirs[:] = [] # don't descend further
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   476
        elif followsym:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   477
            newdirs = []
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   478
            for d in dirs:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   479
                fname = os.path.join(root, d)
14227
94985b5a8278 scmutil: rename local function _add_dir_if_not_there
Adrian Buehlmann <adrian@cadifra.com>
parents: 14226
diff changeset
   480
                if adddir(seen_dirs, fname):
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   481
                    if os.path.islink(fname):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   482
                        for hgname in walkrepos(fname, True, seen_dirs):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   483
                            yield hgname
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   484
                    else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   485
                        newdirs.append(d)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
   486
            dirs[:] = newdirs
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   487
14224
f4189866c76c rename scmutil.os_rcpath to osrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14220
diff changeset
   488
def osrcpath():
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
   489
    '''return default os-specific hgrc search path'''
14225
f0ca440b5722 rename scmutil.system_rcpath to systemrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14224
diff changeset
   490
    path = systemrcpath()
14226
73cca883370d rename scmutil.user_rcpath to userrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14225
diff changeset
   491
    path.extend(userrcpath())
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
   492
    path = [os.path.normpath(f) for f in path]
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
   493
    return path
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
   494
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   495
_rcpath = None
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   496
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   497
def rcpath():
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   498
    '''return hgrc search path. if env var HGRCPATH is set, use it.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   499
    for each item in path, if directory, use files ending in .rc,
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   500
    else use item.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   501
    make HGRCPATH empty to only look in .hg/hgrc of current repo.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   502
    if no HGRCPATH, use default os-specific path.'''
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   503
    global _rcpath
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   504
    if _rcpath is None:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   505
        if 'HGRCPATH' in os.environ:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   506
            _rcpath = []
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   507
            for p in os.environ['HGRCPATH'].split(os.pathsep):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   508
                if not p:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   509
                    continue
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   510
                p = util.expandpath(p)
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   511
                if os.path.isdir(p):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   512
                    for f, kind in osutil.listdir(p):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   513
                        if f.endswith('.rc'):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   514
                            _rcpath.append(os.path.join(p, f))
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   515
                else:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   516
                    _rcpath.append(p)
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   517
        else:
14224
f4189866c76c rename scmutil.os_rcpath to osrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14220
diff changeset
   518
            _rcpath = osrcpath()
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
   519
    return _rcpath
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   520
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   521
if os.name != 'nt':
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   522
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   523
    def rcfiles(path):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   524
        rcs = [os.path.join(path, 'hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   525
        rcdir = os.path.join(path, 'hgrc.d')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   526
        try:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   527
            rcs.extend([os.path.join(rcdir, f)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   528
                        for f, kind in osutil.listdir(rcdir)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   529
                        if f.endswith(".rc")])
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   530
        except OSError:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   531
            pass
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   532
        return rcs
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   533
14225
f0ca440b5722 rename scmutil.system_rcpath to systemrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14224
diff changeset
   534
    def systemrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   535
        path = []
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   536
        if sys.platform == 'plan9':
16436
e98460f6089d scmutil: fix systemrcpath regression introduced in f5dd179bfa4a
Wolfgang Treutterer <Wolfgang.Treutterer@ipp.mpg.de>
parents: 16390
diff changeset
   537
            root = 'lib/mercurial'
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   538
        else:
16436
e98460f6089d scmutil: fix systemrcpath regression introduced in f5dd179bfa4a
Wolfgang Treutterer <Wolfgang.Treutterer@ipp.mpg.de>
parents: 16390
diff changeset
   539
            root = 'etc/mercurial'
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   540
        # old mod_python does not set sys.argv
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   541
        if len(getattr(sys, 'argv', [])) > 0:
14527
5867bd6e7cf5 scmutil: improve path calculation for install-relative RC files (issue2841)
Matt Mackall <mpm@selenic.com>
parents: 14484
diff changeset
   542
            p = os.path.dirname(os.path.dirname(sys.argv[0]))
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   543
            path.extend(rcfiles(os.path.join(p, root)))
16436
e98460f6089d scmutil: fix systemrcpath regression introduced in f5dd179bfa4a
Wolfgang Treutterer <Wolfgang.Treutterer@ipp.mpg.de>
parents: 16390
diff changeset
   544
        path.extend(rcfiles('/' + root))
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   545
        return path
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   546
14226
73cca883370d rename scmutil.user_rcpath to userrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14225
diff changeset
   547
    def userrcpath():
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   548
        if sys.platform == 'plan9':
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   549
            return [os.environ['home'] + '/lib/hgrc']
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   550
        else:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents: 16379
diff changeset
   551
            return [os.path.expanduser('~/.hgrc')]
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   552
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   553
else:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   554
16808
572d5e254f20 scmutil: use _winreg.HKEY_LOCAL_MACHINE
Adrian Buehlmann <adrian@cadifra.com>
parents: 16791
diff changeset
   555
    import _winreg
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   556
14225
f0ca440b5722 rename scmutil.system_rcpath to systemrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14224
diff changeset
   557
    def systemrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   558
        '''return default os-specific hgrc search path'''
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   559
        rcpath = []
14236
e949a008999d rename util.executable_path to executablepath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14230
diff changeset
   560
        filename = util.executablepath()
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   561
        # Use mercurial.ini found in directory with hg.exe
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   562
        progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   563
        if os.path.isfile(progrc):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   564
            rcpath.append(progrc)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   565
            return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   566
        # Use hgrc.d found in directory with hg.exe
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   567
        progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   568
        if os.path.isdir(progrcd):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   569
            for f, kind in osutil.listdir(progrcd):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   570
                if f.endswith('.rc'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   571
                    rcpath.append(os.path.join(progrcd, f))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   572
            return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   573
        # else look for a system rcpath in the registry
14230
d51630301241 rename util.lookup_reg to lookupreg
Adrian Buehlmann <adrian@cadifra.com>
parents: 14227
diff changeset
   574
        value = util.lookupreg('SOFTWARE\\Mercurial', None,
16808
572d5e254f20 scmutil: use _winreg.HKEY_LOCAL_MACHINE
Adrian Buehlmann <adrian@cadifra.com>
parents: 16791
diff changeset
   575
                               _winreg.HKEY_LOCAL_MACHINE)
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   576
        if not isinstance(value, str) or not value:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   577
            return rcpath
16068
73aaff46175b use util.localpath() instead of 'str.replace()' to unify path conversion
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15993
diff changeset
   578
        value = util.localpath(value)
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   579
        for p in value.split(os.pathsep):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   580
            if p.lower().endswith('mercurial.ini'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   581
                rcpath.append(p)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   582
            elif os.path.isdir(p):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   583
                for f, kind in osutil.listdir(p):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   584
                    if f.endswith('.rc'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   585
                        rcpath.append(os.path.join(p, f))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   586
        return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   587
14226
73cca883370d rename scmutil.user_rcpath to userrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14225
diff changeset
   588
    def userrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   589
        '''return os-specific hgrc search path to the user dir'''
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   590
        home = os.path.expanduser('~')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   591
        path = [os.path.join(home, 'mercurial.ini'),
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   592
                os.path.join(home, '.hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   593
        userprofile = os.environ.get('USERPROFILE')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   594
        if userprofile:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   595
            path.append(os.path.join(userprofile, 'mercurial.ini'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   596
            path.append(os.path.join(userprofile, '.hgrc'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
   597
        return path
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   598
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   599
def revsingle(repo, revspec, default='.'):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   600
    if not revspec:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   601
        return repo[default]
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   602
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   603
    l = revrange(repo, [revspec])
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   604
    if len(l) < 1:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   605
        raise util.Abort(_('empty revision set'))
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   606
    return repo[l[-1]]
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   607
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   608
def revpair(repo, revs):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   609
    if not revs:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   610
        return repo.dirstate.p1(), None
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   611
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   612
    l = revrange(repo, revs)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   613
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   614
    if len(l) == 0:
16790
2a0efa1112ac revpair: handle odd ranges (issue3474)
Matt Mackall <mpm@selenic.com>
parents: 16479
diff changeset
   615
        if revs:
2a0efa1112ac revpair: handle odd ranges (issue3474)
Matt Mackall <mpm@selenic.com>
parents: 16479
diff changeset
   616
            raise util.Abort(_('empty revision range'))
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   617
        return repo.dirstate.p1(), None
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   618
16790
2a0efa1112ac revpair: handle odd ranges (issue3474)
Matt Mackall <mpm@selenic.com>
parents: 16479
diff changeset
   619
    if len(l) == 1 and len(revs) == 1 and _revrangesep not in revs[0]:
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   620
        return repo.lookup(l[0]), None
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   621
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   622
    return repo.lookup(l[0]), repo.lookup(l[-1])
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   623
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   624
_revrangesep = ':'
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   625
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   626
def revrange(repo, revs):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   627
    """Yield revision as strings from a list of revision specifications."""
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   628
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   629
    def revfix(repo, val, defval):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   630
        if not val and val != 0 and defval is not None:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   631
            return defval
16379
5cbfbb838198 scmutil: use context instead of lookup
Matt Mackall <mpm@selenic.com>
parents: 16208
diff changeset
   632
        return repo[val].rev()
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   633
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   634
    seen, l = set(), []
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   635
    for spec in revs:
16390
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   636
        if l and not seen:
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   637
            seen = set(l)
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   638
        # attempt to parse old-style ranges first to deal with
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   639
        # things like old-tag which contain query metacharacters
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   640
        try:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   641
            if isinstance(spec, int):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   642
                seen.add(spec)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   643
                l.append(spec)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   644
                continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   645
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   646
            if _revrangesep in spec:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   647
                start, end = spec.split(_revrangesep, 1)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   648
                start = revfix(repo, start, 0)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   649
                end = revfix(repo, end, len(repo) - 1)
17992
c95210b82c0e clfilter: remove usage of `range` and `xrange` in scmutil.revrange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17937
diff changeset
   650
                rangeiter = repo.changelog.revs(start, end)
16390
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   651
                if not seen and not l:
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   652
                    # by far the most common case: revs = ["-1:0"]
17992
c95210b82c0e clfilter: remove usage of `range` and `xrange` in scmutil.revrange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17937
diff changeset
   653
                    l = list(rangeiter)
16390
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   654
                    # defer syncing seen until next iteration
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   655
                    continue
17992
c95210b82c0e clfilter: remove usage of `range` and `xrange` in scmutil.revrange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17937
diff changeset
   656
                newrevs = set(rangeiter)
16390
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   657
                if seen:
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   658
                    newrevs.difference_update(seen)
16814
9da5a2864f3f scmutil: seen.union should be seen.update (issue3476)
Bryan O'Sullivan <bryano@fb.com>
parents: 16790
diff changeset
   659
                    seen.update(newrevs)
16390
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   660
                else:
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   661
                    seen = newrevs
4df76d5506a9 scmutil: speed up revrange
Bryan O'Sullivan <bryano@fb.com>
parents: 16383
diff changeset
   662
                l.extend(sorted(newrevs, reverse=start > end))
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   663
                continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   664
            elif spec and spec in repo: # single unquoted rev
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   665
                rev = revfix(repo, spec, None)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   666
                if rev in seen:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   667
                    continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   668
                seen.add(rev)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   669
                l.append(rev)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   670
                continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   671
        except error.RepoLookupError:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   672
            pass
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   673
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   674
        # fall through to new-style queries if old-style fails
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   675
        m = revset.match(repo.ui, spec)
17675
8575f4a2126e clfilter: remove usage of `range` in favor of iteration over changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17649
diff changeset
   676
        dl = [r for r in m(repo, list(repo)) if r not in seen]
17037
419966126a05 scmutil: speed up new-style range extension
Bryan O'Sullivan <bryano@fb.com>
parents: 17007
diff changeset
   677
        l.extend(dl)
419966126a05 scmutil: speed up new-style range extension
Bryan O'Sullivan <bryano@fb.com>
parents: 17007
diff changeset
   678
        seen.update(dl)
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   679
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
   680
    return l
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   681
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   682
def expandpats(pats):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   683
    if not util.expandglobs:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   684
        return list(pats)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   685
    ret = []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   686
    for p in pats:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   687
        kind, name = matchmod._patsplit(p, None)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   688
        if kind is None:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   689
            try:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   690
                globbed = glob.glob(name)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   691
            except re.error:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   692
                globbed = [name]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   693
            if globbed:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   694
                ret.extend(globbed)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   695
                continue
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   696
        ret.append(p)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   697
    return ret
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   698
16171
336e61875335 graphlog: restore FILE glob expansion on Windows
Patrick Mezard <patrick@mezard.eu>
parents: 16167
diff changeset
   699
def matchandpats(ctx, pats=[], opts={}, globbed=False, default='relpath'):
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   700
    if pats == ("",):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   701
        pats = []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   702
    if not globbed and default == 'relpath':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   703
        pats = expandpats(pats or [])
14670
19197fa4c41c scmutil: match now accepts a context or a repo
Matt Mackall <mpm@selenic.com>
parents: 14669
diff changeset
   704
19197fa4c41c scmutil: match now accepts a context or a repo
Matt Mackall <mpm@selenic.com>
parents: 14669
diff changeset
   705
    m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
14669
2d2604adfdd6 context: add a match builder method
Matt Mackall <mpm@selenic.com>
parents: 14527
diff changeset
   706
                         default)
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   707
    def badfn(f, msg):
14671
35c2cc322ba8 scmutil: switch match users to supplying contexts
Matt Mackall <mpm@selenic.com>
parents: 14670
diff changeset
   708
        ctx._repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   709
    m.bad = badfn
16171
336e61875335 graphlog: restore FILE glob expansion on Windows
Patrick Mezard <patrick@mezard.eu>
parents: 16167
diff changeset
   710
    return m, pats
336e61875335 graphlog: restore FILE glob expansion on Windows
Patrick Mezard <patrick@mezard.eu>
parents: 16167
diff changeset
   711
336e61875335 graphlog: restore FILE glob expansion on Windows
Patrick Mezard <patrick@mezard.eu>
parents: 16167
diff changeset
   712
def match(ctx, pats=[], opts={}, globbed=False, default='relpath'):
336e61875335 graphlog: restore FILE glob expansion on Windows
Patrick Mezard <patrick@mezard.eu>
parents: 16167
diff changeset
   713
    return matchandpats(ctx, pats, opts, globbed, default)[0]
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   714
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   715
def matchall(repo):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   716
    return matchmod.always(repo.root, repo.getcwd())
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   717
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   718
def matchfiles(repo, files):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   719
    return matchmod.exact(repo.root, repo.getcwd(), files)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   720
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   721
def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   722
    if dry_run is None:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   723
        dry_run = opts.get('dry_run')
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   724
    if similarity is None:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   725
        similarity = float(opts.get('similarity') or 0)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   726
    # we'd use status here, except handling of symlinks and ignore is tricky
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   727
    added, unknown, deleted, removed = [], [], [], []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   728
    audit_path = pathauditor(repo.root)
14671
35c2cc322ba8 scmutil: switch match users to supplying contexts
Matt Mackall <mpm@selenic.com>
parents: 14670
diff changeset
   729
    m = match(repo[None], pats, opts)
16167
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   730
    rejected = []
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   731
    m.bad = lambda x, y: rejected.append(x)
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   732
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   733
    for abs in repo.walk(m):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   734
        target = repo.wjoin(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   735
        good = True
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   736
        try:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   737
            audit_path(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   738
        except (OSError, util.Abort):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   739
            good = False
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   740
        rel = m.rel(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   741
        exact = m.exact(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   742
        if good and abs not in repo.dirstate:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   743
            unknown.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   744
            if repo.ui.verbose or not exact:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   745
                repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   746
        elif (repo.dirstate[abs] != 'r' and
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   747
              (not good or not os.path.lexists(target) or
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   748
               (os.path.isdir(target) and not os.path.islink(target)))):
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   749
            deleted.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   750
            if repo.ui.verbose or not exact:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   751
                repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   752
        # for finding renames
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   753
        elif repo.dirstate[abs] == 'r':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   754
            removed.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   755
        elif repo.dirstate[abs] == 'a':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   756
            added.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   757
    copies = {}
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   758
    if similarity > 0:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   759
        for old, new, score in similar.findrenames(repo,
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   760
                added + unknown, removed + deleted, similarity):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   761
            if repo.ui.verbose or not m.exact(old) or not m.exact(new):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   762
                repo.ui.status(_('recording removal of %s as rename to %s '
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   763
                                 '(%d%% similar)\n') %
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   764
                               (m.rel(old), m.rel(new), score * 100))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   765
            copies[new] = old
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   766
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   767
    if not dry_run:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   768
        wctx = repo[None]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   769
        wlock = repo.wlock()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   770
        try:
14435
5f6090e559fa context: make forget work like commands.forget
Matt Mackall <mpm@selenic.com>
parents: 14404
diff changeset
   771
            wctx.forget(deleted)
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   772
            wctx.add(unknown)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   773
            for new, old in copies.iteritems():
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   774
                wctx.copy(old, new)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   775
        finally:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   776
            wlock.release()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   777
16167
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   778
    for f in rejected:
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   779
        if f in m.files():
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   780
            return 1
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   781
    return 0
94a8396c9305 addremove: return 1 if we failed to handle any explicit files
Matt Mackall <mpm@selenic.com>
parents: 16115
diff changeset
   782
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   783
def updatedir(ui, repo, patches, similarity=0):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   784
    '''Update dirstate after patch application according to metadata'''
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   785
    if not patches:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   786
        return []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   787
    copies = []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   788
    removes = set()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   789
    cfiles = patches.keys()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   790
    cwd = repo.getcwd()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   791
    if cwd:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   792
        cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   793
    for f in patches:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   794
        gp = patches[f]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   795
        if not gp:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   796
            continue
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   797
        if gp.op == 'RENAME':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   798
            copies.append((gp.oldpath, gp.path))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   799
            removes.add(gp.oldpath)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   800
        elif gp.op == 'COPY':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   801
            copies.append((gp.oldpath, gp.path))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   802
        elif gp.op == 'DELETE':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   803
            removes.add(gp.path)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   804
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   805
    wctx = repo[None]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   806
    for src, dst in copies:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   807
        dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   808
    if (not similarity) and removes:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   809
        wctx.remove(sorted(removes), True)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   810
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   811
    for f in patches:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   812
        gp = patches[f]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   813
        if gp and gp.mode:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   814
            islink, isexec = gp.mode
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   815
            dst = repo.wjoin(gp.path)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   816
            # patch won't create empty files
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   817
            if gp.op == 'ADD' and not os.path.lexists(dst):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   818
                flags = (isexec and 'x' or '') + (islink and 'l' or '')
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   819
                repo.wwrite(gp.path, '', flags)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   820
            util.setflags(dst, islink, isexec)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   821
    addremove(repo, cfiles, similarity=similarity)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   822
    files = patches.keys()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   823
    files.extend([r for r in removes if r not in files])
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   824
    return sorted(files)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   825
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   826
def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   827
    """Update the dirstate to reflect the intent of copying src to dst. For
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   828
    different reasons it might not end with dst being marked as copied from src.
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   829
    """
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   830
    origsrc = repo.dirstate.copied(src) or src
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   831
    if dst == origsrc: # copying back a copy?
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   832
        if repo.dirstate[dst] not in 'mn' and not dryrun:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   833
            repo.dirstate.normallookup(dst)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   834
    else:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   835
        if repo.dirstate[origsrc] == 'a' and origsrc == src:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   836
            if not ui.quiet:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   837
                ui.warn(_("%s has not been committed yet, so no copy "
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   838
                          "data will be stored for %s.\n")
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   839
                        % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   840
            if repo.dirstate[dst] in '?r' and not dryrun:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   841
                wctx.add([dst])
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   842
        elif not dryrun:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
   843
            wctx.copy(origsrc, dst)
14482
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   844
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   845
def readrequires(opener, supported):
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   846
    '''Reads and parses .hg/requires and checks if all entries found
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   847
    are in the list of supported features.'''
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   848
    requirements = set(opener.read("requires").splitlines())
14746
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
   849
    missings = []
14482
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   850
    for r in requirements:
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   851
        if r not in supported:
14484
4582a4dd1817 requires: note apparent corruption
Matt Mackall <mpm@selenic.com>
parents: 14483
diff changeset
   852
            if not r or not r[0].isalnum():
4582a4dd1817 requires: note apparent corruption
Matt Mackall <mpm@selenic.com>
parents: 14483
diff changeset
   853
                raise error.RequirementError(_(".hg/requires file is corrupt"))
14746
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
   854
            missings.append(r)
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
   855
    missings.sort()
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
   856
    if missings:
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   857
        raise error.RequirementError(
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   858
            _("unknown repository format: requires features '%s' (upgrade "
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16479
diff changeset
   859
              "Mercurial)") % "', '".join(missings))
14482
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
   860
    return requirements
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   861
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   862
class filecacheentry(object):
18315
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   863
    def __init__(self, path, stat=True):
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   864
        self.path = path
18315
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   865
        self.cachestat = None
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   866
        self._cacheable = None
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   867
18315
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   868
        if stat:
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   869
            self.cachestat = filecacheentry.stat(self.path)
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   870
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   871
            if self.cachestat:
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   872
                self._cacheable = self.cachestat.cacheable()
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   873
            else:
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   874
                # None means we don't know yet
216230643ae2 filecache: allow filecacheentry to be created without stating in __init__
Idan Kamara <idankk86@gmail.com>
parents: 18213
diff changeset
   875
                self._cacheable = None
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   876
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   877
    def refresh(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   878
        if self.cacheable():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   879
            self.cachestat = filecacheentry.stat(self.path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   880
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   881
    def cacheable(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   882
        if self._cacheable is not None:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   883
            return self._cacheable
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   884
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   885
        # we don't know yet, assume it is for now
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   886
        return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   887
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   888
    def changed(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   889
        # no point in going further if we can't cache it
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   890
        if not self.cacheable():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   891
            return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   892
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   893
        newstat = filecacheentry.stat(self.path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   894
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   895
        # we may not know if it's cacheable yet, check again now
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   896
        if newstat and self._cacheable is None:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   897
            self._cacheable = newstat.cacheable()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   898
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   899
            # check again
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   900
            if not self._cacheable:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   901
                return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   902
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   903
        if self.cachestat != newstat:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   904
            self.cachestat = newstat
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   905
            return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   906
        else:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   907
            return False
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   908
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   909
    @staticmethod
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   910
    def stat(path):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   911
        try:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   912
            return util.cachestat(path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   913
        except OSError, e:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   914
            if e.errno != errno.ENOENT:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   915
                raise
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   916
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   917
class filecache(object):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   918
    '''A property like decorator that tracks a file under .hg/ for updates.
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   919
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   920
    Records stat info when called in _filecache.
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   921
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   922
    On subsequent calls, compares old stat info with new info, and recreates
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   923
    the object when needed, updating the new stat info in _filecache.
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   924
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   925
    Mercurial either atomic renames or appends for files under .hg,
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   926
    so to ensure the cache is reliable we need the filesystem to be able
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   927
    to tell us if a file has been replaced. If it can't, we fallback to
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   928
    recreating the object on every call (essentially the same behaviour as
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   929
    propertycache).'''
16198
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   930
    def __init__(self, path):
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   931
        self.path = path
16198
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   932
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   933
    def join(self, obj, fname):
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   934
        """Used to compute the runtime path of the cached file.
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   935
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   936
        Users should subclass filecache and provide their own version of this
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   937
        function to call the appropriate join function on 'obj' (an instance
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   938
        of the class that its member function was decorated).
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   939
        """
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   940
        return obj.join(fname)
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   941
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   942
    def __call__(self, func):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   943
        self.func = func
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   944
        self.name = func.__name__
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   945
        return self
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   946
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   947
    def __get__(self, obj, type=None):
16115
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   948
        # do we need to check if the file changed?
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   949
        if self.name in obj.__dict__:
18316
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   950
            assert self.name in obj._filecache, self.name
16115
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   951
            return obj.__dict__[self.name]
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   952
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   953
        entry = obj._filecache.get(self.name)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   954
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   955
        if entry:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   956
            if entry.changed():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   957
                entry.obj = self.func(obj)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   958
        else:
16198
fa8488565afd filecache: refactor path join logic to a function
Idan Kamara <idankk86@gmail.com>
parents: 16115
diff changeset
   959
            path = self.join(obj, self.path)
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   960
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   961
            # We stat -before- creating the object so our cache doesn't lie if
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   962
            # a writer modified between the time we read and stat
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   963
            entry = filecacheentry(path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   964
            entry.obj = self.func(obj)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   965
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   966
            obj._filecache[self.name] = entry
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   967
16115
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   968
        obj.__dict__[self.name] = entry.obj
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
   969
        return entry.obj
16115
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   970
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   971
    def __set__(self, obj, value):
18316
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   972
        if self.name not in obj._filecache:
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   973
            # we add an entry for the missing value because X in __dict__
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   974
            # implies X in _filecache
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   975
            ce = filecacheentry(self.join(obj, self.path), False)
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   976
            obj._filecache[self.name] = ce
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   977
        else:
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   978
            ce = obj._filecache[self.name]
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   979
f36375576ed5 filecache: create an entry in _filecache when __set__ is called for a missing one
Idan Kamara <idankk86@gmail.com>
parents: 18315
diff changeset
   980
        ce.obj = value # update cached copy
16115
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   981
        obj.__dict__[self.name] = value # update copy returned by obj.x
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   982
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   983
    def __delete__(self, obj):
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   984
        try:
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   985
            del obj.__dict__[self.name]
236bb604dc39 scmutil: update cached copy when filecached attribute is assigned (issue3263)
Idan Kamara <idankk86@gmail.com>
parents: 16068
diff changeset
   986
        except KeyError:
18177
203b7a759218 scmutil: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents: 17992
diff changeset
   987
            raise AttributeError(self.name)