def revpair(repo, revs): if not revs: return repo.dirstate.p1(), None l = revrange(repo, revs) if not l: first = second = None elif l.isascending(): first = l.min() second = l.max() elif l.isdescending(): first = l.max() second = l.min() else: first = l.first() second = l.last() if first is None: raise error.Abort(_('empty revision range')) if (first == second and len(revs) >= 2 and not all(revrange(repo, [r]) for r in revs)): raise error.Abort(_('empty revision on one side of range')) # if top-level is range expression, the result must always be a pair if first == second and len(revs) == 1 and not _pairspec(revs[0]): return repo.lookup(first), None return repo.lookup(first), repo.lookup(second)
def __init__(self, ui, repo, opts): self.ui = ui self.repo = repo self.address = opts['address'] if not util.safehasattr(SocketServer, 'UnixStreamServer'): raise error.Abort(_('unsupported platform')) if not self.address: raise error.Abort(_('no socket path specified with --address'))
def checknewlabel(repo, lbl, kind): # Do not use the "kind" parameter in ui output. # It makes strings difficult to translate. if lbl in ['tip', '.', 'null']: raise error.Abort(_("the name '%s' is reserved") % lbl) for c in (':', '\0', '\n', '\r'): if c in lbl: raise error.Abort(_("%r cannot be used in a name") % c) try: int(lbl) raise error.Abort(_("cannot use an integer as a name")) except ValueError: pass
def tolocal(s): """ Convert a string from internal UTF-8 to local encoding All internal strings should be UTF-8 but some repos before the implementation of locale support may contain latin1 or possibly other character sets. We attempt to decode everything strictly using UTF-8, then Latin-1, and failing that, we use UTF-8 and replace unknown characters. The localstr class is used to cache the known UTF-8 encoding of strings next to their local representation to allow lossless round-trip conversion back to UTF-8. >>> u = 'foo: \\xc3\\xa4' # utf-8 >>> l = tolocal(u) >>> l 'foo: ?' >>> fromlocal(l) 'foo: \\xc3\\xa4' >>> u2 = 'foo: \\xc3\\xa1' >>> d = { l: 1, tolocal(u2): 2 } >>> len(d) # no collision 2 >>> 'foo: ?' in d False >>> l1 = 'foo: \\xe4' # historical latin1 fallback >>> l = tolocal(l1) >>> l 'foo: ?' >>> fromlocal(l) # magically in utf-8 'foo: \\xc3\\xa4' """ try: try: # make sure string is actually stored in UTF-8 u = s.decode('UTF-8') if encoding == 'UTF-8': # fast path return s r = u.encode(encoding, "replace") if u == r.decode(encoding): # r is a safe, non-lossy encoding of s return r return localstr(s, r) except UnicodeDecodeError: # we should only get here if we're looking at an ancient changeset try: u = s.decode(fallbackencoding) r = u.encode(encoding, "replace") if u == r.decode(encoding): # r is a safe, non-lossy encoding of s return r return localstr(u.encode('UTF-8'), r) except UnicodeDecodeError: u = s.decode("utf-8", "replace") # last ditch return u.encode(encoding, "replace") # can't round-trip except LookupError, k: raise error.Abort(k, hint="please check your locale settings")
def _addpath(self, f, state, mode, size, mtime): oldstate = self[f] if state == 'a' or oldstate == 'r': scmutil.checkfilename(f) if f in self._dirs: raise error.Abort(_('directory %r already in dirstate') % f) # shadows for d in util.finddirs(f): if d in self._dirs: break if d in self._map and self[d] != 'r': raise error.Abort( _('file %r in dirstate clashes with %r') % (d, f)) if oldstate in "?r" and "_dirs" in self.__dict__: self._dirs.addpath(f) self._dirty = True self._map[f] = dirstatetuple(state, mode, size, mtime)
def revsingle(repo, revspec, default='.'): if not revspec and revspec != 0: return repo[default] l = revrange(repo, [revspec]) if not l: raise error.Abort(_('empty revision set')) return repo[l.last()]
def _opendirstatefile(self): fp, mode = _trypending(self._root, self._opener, self._filename) if self._pendingmode is not None and self._pendingmode != mode: fp.close() raise error.Abort( _('working directory state may be ' 'changed parallelly')) self._pendingmode = mode return fp
def __call__(self, f): if f in self._newfiles: return fl = encoding.lower(f) if fl in self._loweredfiles and f not in self._dirstate: msg = _('possible case-folding collision for %s') % f if self._abort: raise error.Abort(msg) self._ui.warn(_("warning: %s\n") % msg) self._loweredfiles.add(fl) self._newfiles.add(f)
def checkportable(ui, f): '''Check if filename f is portable and warn or abort depending on config''' checkfilename(f) abort, warn = checkportabilityalert(ui) if abort or warn: msg = util.checkwinfilename(f) if msg: msg = "%s: %r" % (msg, f) if abort: raise error.Abort(msg) ui.warn(_("warning: %s\n") % msg)
def serveone(self): cmd = self.client.readline()[:-1] if cmd: handler = self.capabilities.get(cmd) if handler: handler(self) else: # clients are expected to check what commands are supported by # looking at the servers capabilities raise error.Abort(_('unknown command %s') % cmd) return cmd != ''
def __call__(self, path, mode="r", text=False, atomictemp=False, notindexed=False): '''Open ``path`` file, which is relative to vfs root. Newly created directories are marked as "not to be indexed by the content indexing service", if ``notindexed`` is specified for "write" mode access. ''' if self._audit: r = util.checkosfilename(path) if r: raise error.Abort("%s: %r" % (r, path)) self.audit(path) f = self.join(path) if not text and "b" not in mode: mode += "b" # for that other OS nlink = -1 if mode not in ('r', 'rb'): dirname, basename = util.split(f) # If basename is empty, then the path is malformed because it points # to a directory. Let the posixfile() call below raise IOError. if basename: if atomictemp: util.ensuredirs(dirname, self.createmode, notindexed) return util.atomictempfile(f, mode, self.createmode) try: if 'w' in mode: util.unlink(f) nlink = 0 else: # nlinks() may behave differently for files on Windows # shares if the file is open. fd = util.posixfile(f) nlink = util.nlinks(f) if nlink < 1: nlink = 2 # force mktempcopy (issue1922) fd.close() except (OSError, IOError) as e: if e.errno != errno.ENOENT: raise nlink = 0 util.ensuredirs(dirname, self.createmode, notindexed) if nlink > 0: if self._trustnlink is None: self._trustnlink = nlink > 1 or util.checknlink(f) if nlink > 1 or not self._trustnlink: util.rename(util.mktempcopy(f), f) fp = util.posixfile(f, mode) if nlink == 0: self._fixfilemode(f) return fp
def fromlocal(s): """ Convert a string from the local character encoding to UTF-8 We attempt to decode strings using the encoding mode set by HGENCODINGMODE, which defaults to 'strict'. In this mode, unknown characters will cause an error message. Other modes include 'replace', which replaces unknown characters with a special Unicode character, and 'ignore', which drops the character. """ # can we do a lossless round-trip? if isinstance(s, localstr): return s._utf8 try: return s.decode(encoding, encodingmode).encode("utf-8") except UnicodeDecodeError as inst: sub = s[max(0, inst.start - 10):inst.start + 10] raise error.Abort("decoding near '%s': %s!" % (sub, inst)) except LookupError as k: raise error.Abort(k, hint="please check your locale settings")
def __init__(self, **opts): for k in self.__slots__: v = opts.get(k) if v is None: v = self.defaults[k] setattr(self, k, v) try: self.context = int(self.context) except ValueError: raise error.Abort( _('diff context lines count must be ' 'an integer, not %r') % self.context)
def subrepo(ctx, path): # subrepo inherently violates our import layering rules # because it wants to make repo objects from deep inside the stack # so we manually delay the circular imports to not break # scripts that don't use our demand-loading global hg import hg as h hg = h util.path_auditor(ctx._repo.root)(path) state = ctx.substate.get(path, nullstate) if state[0].startswith('['): # future expansion raise error.Abort('unknown subrepo source %s' % state[0]) return hgsubrepo(ctx, path, state)
def tolocal(s): """ Convert a string from internal UTF-8 to local encoding All internal strings should be UTF-8 but some repos before the implementation of locale support may contain latin1 or possibly other character sets. We attempt to decode everything strictly using UTF-8, then Latin-1, and failing that, we use UTF-8 and replace unknown characters. The localstr class is used to cache the known UTF-8 encoding of strings next to their local representation to allow lossless round-trip conversion back to UTF-8. >>> u = 'foo: \\xc3\\xa4' # utf-8 >>> l = tolocal(u) >>> l 'foo: ?' >>> fromlocal(l) 'foo: \\xc3\\xa4' >>> u2 = 'foo: \\xc3\\xa1' >>> d = { l: 1, tolocal(u2): 2 } >>> d # no collision {'foo: ?': 1, 'foo: ?': 2} >>> 'foo: ?' in d False >>> l1 = 'foo: \\xe4' # historical latin1 fallback >>> l = tolocal(l1) >>> l 'foo: ?' >>> fromlocal(l) # magically in utf-8 'foo: \\xc3\\xa4' """ for e in ('UTF-8', fallbackencoding): try: u = s.decode(e) # attempt strict decoding r = u.encode(encoding, "replace") if u == r.decode(encoding): # r is a safe, non-lossy encoding of s return r elif e == 'UTF-8': return localstr(s, r) else: return localstr(u.encode('UTF-8'), r) except LookupError, k: raise error.Abort("%s, please check your locale settings" % k) except UnicodeDecodeError: pass
def upperfallback(s): try: if isinstance(s, localstr): u = s._utf8.decode("utf-8") else: u = s.decode(encoding, encodingmode) uu = u.upper() if u == uu: return s # preserve localstring return uu.encode(encoding) except UnicodeError: return s.upper() # we don't know how to fold this except in ASCII except LookupError as k: raise error.Abort(k, hint="please check your locale settings")
def fromlocal(s): """ Convert a string from the local character encoding to UTF-8 We attempt to decode strings using the encoding mode set by HGENCODINGMODE, which defaults to 'strict'. In this mode, unknown characters will cause an error message. Other modes include 'replace', which replaces unknown characters with a special Unicode character, and 'ignore', which drops the character. """ try: return s.decode(encoding, encodingmode).encode("utf-8") except UnicodeDecodeError, inst: sub = s[max(0, inst.start - 10):inst.start + 10] raise error.Abort("decoding near '%s': %s!" % (sub, inst))
def otherparent(self, f): '''Mark as coming from the other parent, always dirty.''' if self._pl[1] == nullid: raise error.Abort( _("setting %r to other parent " "only allowed in merges") % f) if f in self and self[f] == 'n': # merge-like self._addpath(f, 'm', 0, -2, -1) else: # add-like self._addpath(f, 'n', 0, -2, -1) if f in self._copymap: del self._copymap[f]
def _pl(self): try: fp = self._opendirstatefile() st = fp.read(40) fp.close() l = len(st) if l == 40: return st[:20], st[20:40] elif l > 0 and l < 40: raise error.Abort( _('working directory state appears damaged!')) except IOError as err: if err.errno != errno.ENOENT: raise return [nullid, nullid]
def lower(s): "best-effort encoding-aware case-folding of local string s" try: if isinstance(s, localstr): u = s._utf8.decode("utf-8") else: u = s.decode(encoding, encodingmode) lu = u.lower() if u == lu: return s # preserve localstring return lu.encode(encoding) except UnicodeError: return s.lower() # we don't know how to fold this except in ASCII except LookupError, k: raise error.Abort(k, hint="please check your locale settings")
def _load(self): '''fill the entries from the fncache file''' self._dirty = False try: fp = self.vfs('fncache', mode='rb') except IOError: # skip nonexistent file self.entries = set() return self.entries = set(decodedir(fp.read()).splitlines()) if '' in self.entries: fp.seek(0) for n, line in enumerate(fp): if not line.rstrip('\n'): t = _('invalid entry in fncache, line %d') % (n + 1) raise error.Abort(t) fp.close()
def tolocal(s): """ Convert a string from internal UTF-8 to local encoding All internal strings should be UTF-8 but some repos before the implementation of locale support may contain latin1 or possibly other character sets. We attempt to decode everything strictly using UTF-8, then Latin-1, and failing that, we use UTF-8 and replace unknown characters. """ for e in ('UTF-8', fallbackencoding): try: u = s.decode(e) # attempt strict decoding return u.encode(encoding, "replace") except LookupError, k: raise error.Abort("%s, please check your locale settings" % k) except UnicodeDecodeError: pass
def upper(s): "best-effort encoding-aware case-folding of local string s" try: s.decode('ascii') # throw exception for non-ASCII character return s.upper() except UnicodeDecodeError: pass try: if isinstance(s, localstr): u = s._utf8.decode("utf-8") else: u = s.decode(encoding, encodingmode) uu = u.upper() if u == uu: return s # preserve localstring return uu.encode(encoding) except UnicodeError: return s.upper() # we don't know how to fold this except in ASCII except LookupError, k: raise error.Abort(k, hint="please check your locale settings")
def __init__(self, repo, changeid=''): """changeid is a revision number, node, or tag""" # since basectx.__new__ already took care of copying the object, we # don't need to do anything in __init__, so we just exit here if isinstance(changeid, basectx): return if changeid == '': changeid = '.' self._repo = repo if isinstance(changeid, int): try: self._node = repo.changelog.node(changeid) except IndexError: raise error.RepoLookupError( _("unknown revision '%s'") % changeid) self._rev = changeid return if isinstance(changeid, long): changeid = str(changeid) if changeid == '.': self._node = repo.dirstate.p1() self._rev = repo.changelog.rev(self._node) return if changeid == 'null': self._node = nullid self._rev = nullrev return if changeid == 'tip': self._node = repo.changelog.tip() self._rev = repo.changelog.rev(self._node) return if len(changeid) == 20: try: self._node = changeid self._rev = repo.changelog.rev(changeid) return except LookupError: pass try: r = int(changeid) if str(r) != changeid: raise ValueError l = len(repo.changelog) if r < 0: r += l if r < 0 or r >= l: raise ValueError self._rev = r self._node = repo.changelog.node(r) return except (ValueError, OverflowError, IndexError): pass if len(changeid) == 40: try: self._node = bin(changeid) self._rev = repo.changelog.rev(self._node) return except (TypeError, LookupError): pass if changeid in repo._bookmarks: self._node = repo._bookmarks[changeid] self._rev = repo.changelog.rev(self._node) return if changeid in repo._tagscache.tags: self._node = repo._tagscache.tags[changeid] self._rev = repo.changelog.rev(self._node) return try: self._node = repo.branchtip(changeid) self._rev = repo.changelog.rev(self._node) return except error.RepoLookupError: pass self._node = repo.changelog._partialmatch(changeid) if self._node is not None: self._rev = repo.changelog.rev(self._node) return # lookup failed # check if it might have come from damaged dirstate # # XXX we could avoid the unfiltered if we had a recognizable exception # for filtered changeset access if changeid in repo.unfiltered().dirstate.parents(): raise error.Abort( _("working directory has unknown parent '%s'!") % short(changeid)) try: if len(changeid) == 20: changeid = hex(changeid) except TypeError: pass raise error.RepoLookupError(_("unknown revision '%s'") % changeid)
characters will cause an error message. Other modes include 'replace', which replaces unknown characters with a special Unicode character, and 'ignore', which drops the character. """ # can we do a lossless round-trip? if isinstance(s, localstr): return s._utf8 try: return s.decode(encoding, encodingmode).encode("utf-8") except UnicodeDecodeError, inst: sub = s[max(0, inst.start - 10):inst.start + 10] raise error.Abort("decoding near '%s': %s!" % (sub, inst)) except LookupError, k: raise error.Abort(k, hint="please check your locale settings") # How to treat ambiguous-width characters. Set to 'wide' to treat as wide. wide = (os.environ.get("HGENCODINGAMBIGUOUS", "narrow") == "wide" and "WFA" or "WF") def colwidth(s): "Find the column width of a string for display in the local encoding" return ucolwidth(s.decode(encoding, 'replace')) def ucolwidth(d): "Find the column width of a Unicode string for display" eaw = getattr(unicodedata, 'east_asian_width', None)
def _active(self, *args, **kwds): if self.count == 0: raise error.Abort(_( 'cannot use transaction when it is already committed/aborted')) return func(self, *args, **kwds)
def archive(repo, dest, node, kind, decode=True, matchfn=None, prefix='', mtime=None, subrepos=False): '''create archive of repo as it was at node. dest can be name of directory, name of archive file, or file object to write archive to. kind is type of archive to create. decode tells whether to put files through decode filters from hgrc. matchfn is function to filter names of files to write to archive. prefix is name of path to put before every archive member.''' if kind == 'files': if prefix: raise util.Abort(_('cannot give prefix when archiving to files')) else: prefix = tidyprefix(dest, kind, prefix) def write(name, mode, islink, getdata): data = getdata() if decode: data = repo.wwritedata(name, data) archiver.addfile(prefix + name, mode, islink, data) if kind not in archivers: raise util.Abort(_("unknown archive type '%s'") % kind) ctx = repo[node] archiver = archivers[kind](dest, mtime or ctx.date()[0]) if repo.ui.configbool("ui", "archivemeta", True): name = '.hg_archival.txt' if not matchfn or matchfn(name): write(name, 0o644, False, lambda: buildmetadata(ctx)) if matchfn: files = [f for f in ctx.manifest().keys() if matchfn(f)] else: files = ctx.manifest().keys() total = len(files) if total: files.sort() repo.ui.progress(_('archiving'), 0, unit=_('files'), total=total) for i, f in enumerate(files): ff = ctx.flags(f) write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, ctx[f].data) repo.ui.progress(_('archiving'), i + 1, item=f, unit=_('files'), total=total) repo.ui.progress(_('archiving'), None) if subrepos: for subpath in sorted(ctx.substate): sub = ctx.workingsub(subpath) submatch = matchmod.narrowmatcher(subpath, matchfn) total += sub.archive(archiver, prefix, submatch) if total == 0: raise error.Abort(_('no files match the archive pattern')) archiver.done() return total
characters will cause an error message. Other modes include 'replace', which replaces unknown characters with a special Unicode character, and 'ignore', which drops the character. """ # can we do a lossless round-trip? if isinstance(s, localstr): return s._utf8 try: return s.decode(encoding, encodingmode).encode("utf-8") except UnicodeDecodeError, inst: sub = s[max(0, inst.start - 10):inst.start + 10] raise error.Abort("decoding near '%s': %s!" % (sub, inst)) except LookupError, k: raise error.Abort("%s, please check your locale settings" % k) # How to treat ambiguous-width characters. Set to 'wide' to treat as wide. ambiguous = os.environ.get("HGENCODINGAMBIGUOUS", "narrow") def colwidth(s): "Find the column width of a UTF-8 string for display" d = s.decode(encoding, 'replace') if hasattr(unicodedata, 'east_asian_width'): wide = "WF" if ambiguous == "wide": wide = "WFA" w = unicodedata.east_asian_width return sum([w(c) in wide and 2 or 1 for c in d]) return len(d)
def __init__(self, repo, changeid=''): """changeid is a revision number, node, or tag""" if changeid == '': changeid = '.' self._repo = repo if isinstance(changeid, int): self._rev = changeid self._node = repo.changelog.node(changeid) return if isinstance(changeid, long): changeid = str(changeid) if changeid == '.': self._node = repo.dirstate.p1() self._rev = repo.changelog.rev(self._node) return if changeid == 'null': self._node = nullid self._rev = nullrev return if changeid == 'tip': self._rev = len(repo.changelog) - 1 self._node = repo.changelog.node(self._rev) return if len(changeid) == 20: try: self._node = changeid self._rev = repo.changelog.rev(changeid) return except LookupError: pass try: r = int(changeid) if str(r) != changeid: raise ValueError l = len(repo.changelog) if r < 0: r += l if r < 0 or r >= l: raise ValueError self._rev = r self._node = repo.changelog.node(r) return except (ValueError, OverflowError): pass if len(changeid) == 40: try: self._node = bin(changeid) self._rev = repo.changelog.rev(self._node) return except (TypeError, LookupError): pass if changeid in repo._bookmarks: self._node = repo._bookmarks[changeid] self._rev = repo.changelog.rev(self._node) return if changeid in repo._tagscache.tags: self._node = repo._tagscache.tags[changeid] self._rev = repo.changelog.rev(self._node) return if changeid in repo.branchtags(): self._node = repo.branchtags()[changeid] self._rev = repo.changelog.rev(self._node) return self._node = repo.changelog._partialmatch(changeid) if self._node is not None: self._rev = repo.changelog.rev(self._node) return # lookup failed # check if it might have come from damaged dirstate if changeid in repo.dirstate.parents(): raise error.Abort( _("working directory has unknown parent '%s'!") % short(changeid)) try: if len(changeid) == 20: changeid = hex(changeid) except TypeError: pass raise error.RepoLookupError(_("unknown revision '%s'") % changeid)
def getuser(): '''return name of current user''' raise error.Abort( _('user name not available - set USERNAME ' 'environment variable'))