# HG changeset patch # User Martin Geisler # Date 1259798775 -3600 # Node ID e97dd3a8e8d70450dce7b0a0dc8d420ea1d0bbc3 # Parent a7d11deb47dd1873a4be0554415e9c0923255046# Parent 60cefb8b3c85b173b62ad37734bf8e3f680f6710 Merge with stable diff -r 60cefb8b3c85 -r e97dd3a8e8d7 contrib/perf.py --- a/contrib/perf.py Wed Dec 02 14:30:39 2009 +0200 +++ b/contrib/perf.py Thu Dec 03 01:06:15 2009 +0100 @@ -103,9 +103,10 @@ def perflookup(ui, repo, rev): timer(lambda: len(repo.lookup(rev))) -def perflog(ui, repo): +def perflog(ui, repo, **opts): ui.pushbuffer() - timer(lambda: commands.log(ui, repo, rev=[], date='', user='')) + timer(lambda: commands.log(ui, repo, rev=[], date='', user='', + copies=opts.get('rename'))) ui.popbuffer() def perftemplating(ui, repo): @@ -144,7 +145,8 @@ 'perftags': (perftags, []), 'perfdirstate': (perfdirstate, []), 'perfdirstatedirs': (perfdirstate, []), - 'perflog': (perflog, []), + 'perflog': (perflog, + [('', 'rename', False, 'ask log to follow renames')]), 'perftemplating': (perftemplating, []), 'perfdiffwd': (perfdiffwd, []), } diff -r 60cefb8b3c85 -r e97dd3a8e8d7 contrib/zsh_completion --- a/contrib/zsh_completion Wed Dec 02 14:30:39 2009 +0200 +++ b/contrib/zsh_completion Thu Dec 03 01:06:15 2009 +0100 @@ -734,6 +734,11 @@ '*:files:_files' } +_hg_cmd_summary() { + _arguments -s -w : $_hg_global_opts \ + '--remote[check for push and pull]' +} + _hg_cmd_tag() { _arguments -s -w : $_hg_global_opts \ '(--local -l)'{-l,--local}'[make the tag local]' \ diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/convert/convcmd.py --- a/hgext/convert/convcmd.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/convert/convcmd.py Thu Dec 03 01:06:15 2009 +0100 @@ -48,6 +48,8 @@ def convertsource(ui, path, type, rev): exceptions = [] + if type and type not in [s[0] for s in source_converters]: + raise util.Abort(_('%s: invalid source repository type') % type) for name, source, sortmode in source_converters: try: if not type or name == type: @@ -60,6 +62,8 @@ raise util.Abort(_('%s: missing or unsupported repository') % path) def convertsink(ui, path, type): + if type and type not in [s[0] for s in sink_converters]: + raise util.Abort(_('%s: invalid destination repository type') % type) for name, sink in sink_converters: try: if not type or name == type: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/convert/filemap.py --- a/hgext/convert/filemap.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/convert/filemap.py Thu Dec 03 01:06:15 2009 +0100 @@ -10,11 +10,11 @@ from common import SKIPREV, converter_source def rpairs(name): - yield '.', name e = len(name) while e != -1: yield name[:e], name[e+1:] e = name.rfind('/', 0, e) + yield '.', name class filemapper(object): '''Map and filter filenames when importing. @@ -82,7 +82,7 @@ exc = self.lookup(name, self.exclude)[0] else: exc = '' - if not inc or exc: + if (not self.include and exc) or (len(inc) <= len(exc)): return None newpre, pre, suf = self.lookup(name, self.rename) if newpre: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/extdiff.py --- a/hgext/extdiff.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/extdiff.py Thu Dec 03 01:06:15 2009 +0100 @@ -146,10 +146,10 @@ if node2: dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0] elif len(common) > 1: - #we only actually need to get the files to copy back to the working - #dir in this case (because the other cases are: diffing 2 revisions - #or single file -- in which case the file is already directly passed - #to the diff tool). + #we only actually need to get the files to copy back to + #the working dir in this case (because the other cases + #are: diffing 2 revisions or single file -- in which case + #the file is already directly passed to the diff tool). dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot) else: # This lets the diff tool open the changed file directly @@ -169,8 +169,9 @@ dir1b = os.devnull dir2 = os.path.join(dir2root, dir2, common_file) - # Function to quote file/dir names in the argument string - # When not operating in 3-way mode, an empty string is returned for parent2 + # Function to quote file/dir names in the argument string. + # When not operating in 3-way mode, an empty string is + # returned for parent2 replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b, child=dir2) def quote(match): key = match.group()[1:] @@ -258,13 +259,14 @@ doc = _('''\ use %(path)s to diff repository (or selected files) - Show differences between revisions for the specified files, using the - %(path)s program. + Show differences between revisions for the specified files, using + the %(path)s program. - When two revision arguments are given, then changes are shown between - those revisions. If only one revision is specified then that revision is - compared to the working directory, and, when no revisions are specified, - the working directory files are compared to its parent.\ + When two revision arguments are given, then changes are shown + between those revisions. If only one revision is specified then + that revision is compared to the working directory, and, when no + revisions are specified, the working directory files are compared + to its parent.\ ''') % dict(path=util.uirepr(path)) # We must translate the docstring right away since it is diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/inotify/linuxserver.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext/inotify/linuxserver.py Thu Dec 03 01:06:15 2009 +0100 @@ -0,0 +1,429 @@ +# linuxserver.py - inotify status server for linux +# +# Copyright 2006, 2007, 2008 Bryan O'Sullivan +# Copyright 2007, 2008 Brendan Cully +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2, incorporated herein by reference. + +from mercurial.i18n import _ +from mercurial import osutil, util +import common +import server +import errno, os, select, stat, sys, time + +try: + import linux as inotify + from linux import watcher +except ImportError: + raise + +def walkrepodirs(dirstate, absroot): + '''Iterate over all subdirectories of this repo. + Exclude the .hg directory, any nested repos, and ignored dirs.''' + def walkit(dirname, top): + fullpath = server.join(absroot, dirname) + try: + for name, kind in osutil.listdir(fullpath): + if kind == stat.S_IFDIR: + if name == '.hg': + if not top: + return + else: + d = server.join(dirname, name) + if dirstate._ignore(d): + continue + for subdir in walkit(d, False): + yield subdir + except OSError, err: + if err.errno not in server.walk_ignored_errors: + raise + yield fullpath + + return walkit('', True) + +def _explain_watch_limit(ui, dirstate, rootabs): + path = '/proc/sys/fs/inotify/max_user_watches' + try: + limit = int(file(path).read()) + except IOError, err: + if err.errno != errno.ENOENT: + raise + raise util.Abort(_('this system does not seem to ' + 'support inotify')) + ui.warn(_('*** the current per-user limit on the number ' + 'of inotify watches is %s\n') % limit) + ui.warn(_('*** this limit is too low to watch every ' + 'directory in this repository\n')) + ui.warn(_('*** counting directories: ')) + ndirs = len(list(walkrepodirs(dirstate, rootabs))) + ui.warn(_('found %d\n') % ndirs) + newlimit = min(limit, 1024) + while newlimit < ((limit + ndirs) * 1.1): + newlimit *= 2 + ui.warn(_('*** to raise the limit from %d to %d (run as root):\n') % + (limit, newlimit)) + ui.warn(_('*** echo %d > %s\n') % (newlimit, path)) + raise util.Abort(_('cannot watch %s until inotify watch limit is raised') + % rootabs) + +class pollable(object): + """ + Interface to support polling. + The file descriptor returned by fileno() is registered to a polling + object. + Usage: + Every tick, check if an event has happened since the last tick: + * If yes, call handle_events + * If no, call handle_timeout + """ + poll_events = select.POLLIN + instances = {} + poll = select.poll() + + def fileno(self): + raise NotImplementedError + + def handle_events(self, events): + raise NotImplementedError + + def handle_timeout(self): + raise NotImplementedError + + def shutdown(self): + raise NotImplementedError + + def register(self, timeout): + fd = self.fileno() + + pollable.poll.register(fd, pollable.poll_events) + pollable.instances[fd] = self + + self.registered = True + self.timeout = timeout + + def unregister(self): + pollable.poll.unregister(self) + self.registered = False + + @classmethod + def run(cls): + while True: + timeout = None + timeobj = None + for obj in cls.instances.itervalues(): + if obj.timeout is not None and (timeout is None or obj.timeout < timeout): + timeout, timeobj = obj.timeout, obj + try: + events = cls.poll.poll(timeout) + except select.error, err: + if err[0] == errno.EINTR: + continue + raise + if events: + by_fd = {} + for fd, event in events: + by_fd.setdefault(fd, []).append(event) + + for fd, events in by_fd.iteritems(): + cls.instances[fd].handle_pollevents(events) + + elif timeobj: + timeobj.handle_timeout() + +def eventaction(code): + """ + Decorator to help handle events in repowatcher + """ + def decorator(f): + def wrapper(self, wpath): + if code == 'm' and wpath in self.lastevent and \ + self.lastevent[wpath] in 'cm': + return + self.lastevent[wpath] = code + self.timeout = 250 + + f(self, wpath) + + wrapper.func_name = f.func_name + return wrapper + return decorator + +class repowatcher(server.repowatcher, pollable): + """ + Watches inotify events + """ + mask = ( + inotify.IN_ATTRIB | + inotify.IN_CREATE | + inotify.IN_DELETE | + inotify.IN_DELETE_SELF | + inotify.IN_MODIFY | + inotify.IN_MOVED_FROM | + inotify.IN_MOVED_TO | + inotify.IN_MOVE_SELF | + inotify.IN_ONLYDIR | + inotify.IN_UNMOUNT | + 0) + + def __init__(self, ui, dirstate, root): + server.repowatcher.__init__(self, ui, dirstate, root) + + self.lastevent = {} + try: + self.watcher = watcher.watcher() + except OSError, err: + raise util.Abort(_('inotify service not available: %s') % + err.strerror) + self.threshold = watcher.threshold(self.watcher) + self.fileno = self.watcher.fileno + self.register(timeout=None) + + self.handle_timeout() + self.scan() + + def event_time(self): + last = self.last_event + now = time.time() + self.last_event = now + + if last is None: + return 'start' + delta = now - last + if delta < 5: + return '+%.3f' % delta + if delta < 50: + return '+%.2f' % delta + return '+%.1f' % delta + + def add_watch(self, path, mask): + if not path: + return + if self.watcher.path(path) is None: + if self.ui.debugflag: + self.ui.note(_('watching %r\n') % path[self.prefixlen:]) + try: + self.watcher.add(path, mask) + except OSError, err: + if err.errno in (errno.ENOENT, errno.ENOTDIR): + return + if err.errno != errno.ENOSPC: + raise + _explain_watch_limit(self.ui, self.dirstate, self.wprefix) + + def setup(self): + self.ui.note(_('watching directories under %r\n') % self.wprefix) + self.add_watch(self.wprefix + '.hg', inotify.IN_DELETE) + self.check_dirstate() + + def scan(self, topdir=''): + ds = self.dirstate._map.copy() + self.add_watch(server.join(self.wprefix, topdir), self.mask) + for root, dirs, files in server.walk(self.dirstate, self.wprefix, + topdir): + for d in dirs: + self.add_watch(server.join(root, d), self.mask) + wroot = root[self.prefixlen:] + for fn in files: + wfn = server.join(wroot, fn) + self.updatefile(wfn, self.getstat(wfn)) + ds.pop(wfn, None) + wtopdir = topdir + if wtopdir and wtopdir[-1] != '/': + wtopdir += '/' + for wfn, state in ds.iteritems(): + if not wfn.startswith(wtopdir): + continue + try: + st = self.stat(wfn) + except OSError: + status = state[0] + self.deletefile(wfn, status) + else: + self.updatefile(wfn, st) + self.check_deleted('!') + self.check_deleted('r') + + @eventaction('c') + def created(self, wpath): + if wpath == '.hgignore': + self.update_hgignore() + try: + st = self.stat(wpath) + if stat.S_ISREG(st[0]): + self.updatefile(wpath, st) + except OSError: + pass + + @eventaction('m') + def modified(self, wpath): + if wpath == '.hgignore': + self.update_hgignore() + try: + st = self.stat(wpath) + if stat.S_ISREG(st[0]): + if self.dirstate[wpath] in 'lmn': + self.updatefile(wpath, st) + except OSError: + pass + + @eventaction('d') + def deleted(self, wpath): + if wpath == '.hgignore': + self.update_hgignore() + elif wpath.startswith('.hg/'): + if wpath == '.hg/wlock': + self.check_dirstate() + return + + self.deletefile(wpath, self.dirstate[wpath]) + + def process_create(self, wpath, evt): + if self.ui.debugflag: + self.ui.note(_('%s event: created %s\n') % + (self.event_time(), wpath)) + + if evt.mask & inotify.IN_ISDIR: + self.scan(wpath) + else: + self.created(wpath) + + def process_delete(self, wpath, evt): + if self.ui.debugflag: + self.ui.note(_('%s event: deleted %s\n') % + (self.event_time(), wpath)) + + if evt.mask & inotify.IN_ISDIR: + tree = self.tree.dir(wpath) + todelete = [wfn for wfn, ignore in tree.walk('?')] + for fn in todelete: + self.deletefile(fn, '?') + self.scan(wpath) + else: + self.deleted(wpath) + + def process_modify(self, wpath, evt): + if self.ui.debugflag: + self.ui.note(_('%s event: modified %s\n') % + (self.event_time(), wpath)) + + if not (evt.mask & inotify.IN_ISDIR): + self.modified(wpath) + + def process_unmount(self, evt): + self.ui.warn(_('filesystem containing %s was unmounted\n') % + evt.fullpath) + sys.exit(0) + + def handle_pollevents(self, events): + if self.ui.debugflag: + self.ui.note(_('%s readable: %d bytes\n') % + (self.event_time(), self.threshold.readable())) + if not self.threshold(): + if self.registered: + if self.ui.debugflag: + self.ui.note(_('%s below threshold - unhooking\n') % + (self.event_time())) + self.unregister() + self.timeout = 250 + else: + self.read_events() + + def read_events(self, bufsize=None): + events = self.watcher.read(bufsize) + if self.ui.debugflag: + self.ui.note(_('%s reading %d events\n') % + (self.event_time(), len(events))) + for evt in events: + assert evt.fullpath.startswith(self.wprefix) + wpath = evt.fullpath[self.prefixlen:] + + # paths have been normalized, wpath never ends with a '/' + + if wpath.startswith('.hg/') and evt.mask & inotify.IN_ISDIR: + # ignore subdirectories of .hg/ (merge, patches...) + continue + + if evt.mask & inotify.IN_UNMOUNT: + self.process_unmount(wpath, evt) + elif evt.mask & (inotify.IN_MODIFY | inotify.IN_ATTRIB): + self.process_modify(wpath, evt) + elif evt.mask & (inotify.IN_DELETE | inotify.IN_DELETE_SELF | + inotify.IN_MOVED_FROM): + self.process_delete(wpath, evt) + elif evt.mask & (inotify.IN_CREATE | inotify.IN_MOVED_TO): + self.process_create(wpath, evt) + + self.lastevent.clear() + + def handle_timeout(self): + if not self.registered: + if self.ui.debugflag: + self.ui.note(_('%s hooking back up with %d bytes readable\n') % + (self.event_time(), self.threshold.readable())) + self.read_events(0) + self.register(timeout=None) + + self.timeout = None + + def shutdown(self): + self.watcher.close() + + def debug(self): + """ + Returns a sorted list of relatives paths currently watched, + for debugging purposes. + """ + return sorted(tuple[0][self.prefixlen:] for tuple in self.watcher) + +class socketlistener(server.socketlistener, pollable): + """ + Listens for client queries on unix socket inotify.sock + """ + def __init__(self, ui, root, repowatcher, timeout): + server.socketlistener.__init__(self, ui, root, repowatcher, timeout) + self.register(timeout=timeout) + + def handle_timeout(self): + pass + + def handle_pollevents(self, events): + for e in events: + self.accept_connection() + + def shutdown(self): + self.sock.close() + try: + os.unlink(self.sockpath) + if self.realsockpath: + os.unlink(self.realsockpath) + os.rmdir(os.path.dirname(self.realsockpath)) + except OSError, err: + if err.errno != errno.ENOENT: + raise + + def answer_stat_query(self, cs): + if self.repowatcher.timeout: + # We got a query while a rescan is pending. Make sure we + # rescan before responding, or we could give back a wrong + # answer. + self.repowatcher.handle_timeout() + return server.socketlistener.answer_stat_query(self, cs) + +class master(object): + def __init__(self, ui, dirstate, root, timeout=None): + self.ui = ui + self.repowatcher = repowatcher(ui, dirstate, root) + self.socketlistener = socketlistener(ui, root, self.repowatcher, + timeout) + + def shutdown(self): + for obj in pollable.instances.itervalues(): + obj.shutdown() + + def run(self): + self.repowatcher.setup() + self.ui.note(_('finished setup\n')) + if os.getenv('TIME_STARTUP'): + sys.exit(0) + pollable.run() diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/inotify/server.py --- a/hgext/inotify/server.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/inotify/server.py Thu Dec 03 01:06:15 2009 +0100 @@ -1,7 +1,6 @@ -# server.py - inotify status server +# server.py - common entry point for inotify status server # -# Copyright 2006, 2007, 2008 Bryan O'Sullivan -# Copyright 2007, 2008 Brendan Cully +# Copyright 2009 Nicolas Dumazet # # This software may be used and distributed according to the terms of the # GNU General Public License version 2, incorporated herein by reference. @@ -9,13 +8,14 @@ from mercurial.i18n import _ from mercurial import cmdutil, osutil, util import common -import errno, os, select, socket, stat, struct, sys, tempfile, time -try: - import linux as inotify - from linux import watcher -except ImportError: - raise +import errno +import os +import socket +import stat +import struct +import sys +import tempfile class AlreadyStartedException(Exception): pass @@ -34,30 +34,6 @@ walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG) -def walkrepodirs(dirstate, absroot): - '''Iterate over all subdirectories of this repo. - Exclude the .hg directory, any nested repos, and ignored dirs.''' - def walkit(dirname, top): - fullpath = join(absroot, dirname) - try: - for name, kind in osutil.listdir(fullpath): - if kind == stat.S_IFDIR: - if name == '.hg': - if not top: - return - else: - d = join(dirname, name) - if dirstate._ignore(d): - continue - for subdir in walkit(d, False): - yield subdir - except OSError, err: - if err.errno not in walk_ignored_errors: - raise - yield fullpath - - return walkit('', True) - def walk(dirstate, absroot, root): '''Like os.walk, but only yields regular files.''' @@ -94,113 +70,6 @@ return walkit(root, root == '') -def _explain_watch_limit(ui, dirstate, rootabs): - path = '/proc/sys/fs/inotify/max_user_watches' - try: - limit = int(file(path).read()) - except IOError, err: - if err.errno != errno.ENOENT: - raise - raise util.Abort(_('this system does not seem to ' - 'support inotify')) - ui.warn(_('*** the current per-user limit on the number ' - 'of inotify watches is %s\n') % limit) - ui.warn(_('*** this limit is too low to watch every ' - 'directory in this repository\n')) - ui.warn(_('*** counting directories: ')) - ndirs = len(list(walkrepodirs(dirstate, rootabs))) - ui.warn(_('found %d\n') % ndirs) - newlimit = min(limit, 1024) - while newlimit < ((limit + ndirs) * 1.1): - newlimit *= 2 - ui.warn(_('*** to raise the limit from %d to %d (run as root):\n') % - (limit, newlimit)) - ui.warn(_('*** echo %d > %s\n') % (newlimit, path)) - raise util.Abort(_('cannot watch %s until inotify watch limit is raised') - % rootabs) - -class pollable(object): - """ - Interface to support polling. - The file descriptor returned by fileno() is registered to a polling - object. - Usage: - Every tick, check if an event has happened since the last tick: - * If yes, call handle_events - * If no, call handle_timeout - """ - poll_events = select.POLLIN - instances = {} - poll = select.poll() - - def fileno(self): - raise NotImplementedError - - def handle_events(self, events): - raise NotImplementedError - - def handle_timeout(self): - raise NotImplementedError - - def shutdown(self): - raise NotImplementedError - - def register(self, timeout): - fd = self.fileno() - - pollable.poll.register(fd, pollable.poll_events) - pollable.instances[fd] = self - - self.registered = True - self.timeout = timeout - - def unregister(self): - pollable.poll.unregister(self) - self.registered = False - - @classmethod - def run(cls): - while True: - timeout = None - timeobj = None - for obj in cls.instances.itervalues(): - if obj.timeout is not None and (timeout is None or obj.timeout < timeout): - timeout, timeobj = obj.timeout, obj - try: - events = cls.poll.poll(timeout) - except select.error, err: - if err[0] == errno.EINTR: - continue - raise - if events: - by_fd = {} - for fd, event in events: - by_fd.setdefault(fd, []).append(event) - - for fd, events in by_fd.iteritems(): - cls.instances[fd].handle_pollevents(events) - - elif timeobj: - timeobj.handle_timeout() - -def eventaction(code): - """ - Decorator to help handle events in repowatcher - """ - def decorator(f): - def wrapper(self, wpath): - if code == 'm' and wpath in self.lastevent and \ - self.lastevent[wpath] in 'cm': - return - self.lastevent[wpath] = code - self.timeout = 250 - - f(self, wpath) - - wrapper.func_name = f.func_name - return wrapper - return decorator - class directory(object): """ Representing a directory @@ -293,23 +162,11 @@ # path is not tracked pass -class repowatcher(pollable): +class repowatcher(object): """ Watches inotify events """ statuskeys = 'almr!?' - mask = ( - inotify.IN_ATTRIB | - inotify.IN_CREATE | - inotify.IN_DELETE | - inotify.IN_DELETE_SELF | - inotify.IN_MODIFY | - inotify.IN_MOVED_FROM | - inotify.IN_MOVED_TO | - inotify.IN_MOVE_SELF | - inotify.IN_ONLYDIR | - inotify.IN_UNMOUNT | - 0) def __init__(self, ui, dirstate, root): self.ui = ui @@ -317,41 +174,18 @@ self.wprefix = join(root, '') self.prefixlen = len(self.wprefix) - try: - self.watcher = watcher.watcher() - except OSError, err: - raise util.Abort(_('inotify service not available: %s') % - err.strerror) - self.threshold = watcher.threshold(self.watcher) - self.fileno = self.watcher.fileno self.tree = directory() self.statcache = {} self.statustrees = dict([(s, directory()) for s in self.statuskeys]) + self.ds_info = self.dirstate_info() + self.last_event = None - self.lastevent = {} - self.register(timeout=None) - - self.ds_info = self.dirstate_info() - self.handle_timeout() - self.scan() - - def event_time(self): - last = self.last_event - now = time.time() - self.last_event = now - - if last is None: - return 'start' - delta = now - last - if delta < 5: - return '+%.3f' % delta - if delta < 50: - return '+%.2f' % delta - return '+%.1f' % delta + def handle_timeout(self): + pass def dirstate_info(self): try: @@ -362,26 +196,6 @@ raise return 0, 0 - def add_watch(self, path, mask): - if not path: - return - if self.watcher.path(path) is None: - if self.ui.debugflag: - self.ui.note(_('watching %r\n') % path[self.prefixlen:]) - try: - self.watcher.add(path, mask) - except OSError, err: - if err.errno in (errno.ENOENT, errno.ENOTDIR): - return - if err.errno != errno.ENOSPC: - raise - _explain_watch_limit(self.ui, self.dirstate, self.wprefix) - - def setup(self): - self.ui.note(_('watching directories under %r\n') % self.wprefix) - self.add_watch(self.wprefix + '.hg', inotify.IN_DELETE) - self.check_dirstate() - def filestatus(self, fn, st): try: type_, mode, size, time = self.dirstate._map[fn][:4] @@ -455,7 +269,6 @@ if newstatus != 'n': self.statustrees[newstatus].dir(root).files[fn] = newstatus - def check_deleted(self, key): # Files that had been deleted but were present in the dirstate # may have vanished from the dirstate; we must clean them up. @@ -468,33 +281,6 @@ del self.statustrees[key].dir(root).files[fn] del self.tree.dir(root).files[fn] - def scan(self, topdir=''): - ds = self.dirstate._map.copy() - self.add_watch(join(self.wprefix, topdir), self.mask) - for root, dirs, files in walk(self.dirstate, self.wprefix, topdir): - for d in dirs: - self.add_watch(join(root, d), self.mask) - wroot = root[self.prefixlen:] - for fn in files: - wfn = join(wroot, fn) - self.updatefile(wfn, self.getstat(wfn)) - ds.pop(wfn, None) - wtopdir = topdir - if wtopdir and wtopdir[-1] != '/': - wtopdir += '/' - for wfn, state in ds.iteritems(): - if not wfn.startswith(wtopdir): - continue - try: - st = self.stat(wfn) - except OSError: - status = state[0] - self.deletefile(wfn, status) - else: - self.updatefile(wfn, st) - self.check_deleted('!') - self.check_deleted('r') - def check_dirstate(self): ds_info = self.dirstate_info() if ds_info == self.ds_info: @@ -502,11 +288,9 @@ self.ds_info = ds_info if not self.ui.debugflag: self.last_event = None - self.ui.note(_('%s dirstate reload\n') % self.event_time()) self.dirstate.invalidate() self.handle_timeout() self.scan() - self.ui.note(_('%s end dirstate reload\n') % self.event_time()) def update_hgignore(self): # An update of the ignore file can potentially change the @@ -545,139 +329,7 @@ self.statcache.pop(wpath, None) raise - @eventaction('c') - def created(self, wpath): - if wpath == '.hgignore': - self.update_hgignore() - try: - st = self.stat(wpath) - if stat.S_ISREG(st[0]): - self.updatefile(wpath, st) - except OSError: - pass - - @eventaction('m') - def modified(self, wpath): - if wpath == '.hgignore': - self.update_hgignore() - try: - st = self.stat(wpath) - if stat.S_ISREG(st[0]): - if self.dirstate[wpath] in 'lmn': - self.updatefile(wpath, st) - except OSError: - pass - - @eventaction('d') - def deleted(self, wpath): - if wpath == '.hgignore': - self.update_hgignore() - elif wpath.startswith('.hg/'): - if wpath == '.hg/wlock': - self.check_dirstate() - return - - self.deletefile(wpath, self.dirstate[wpath]) - - def process_create(self, wpath, evt): - if self.ui.debugflag: - self.ui.note(_('%s event: created %s\n') % - (self.event_time(), wpath)) - - if evt.mask & inotify.IN_ISDIR: - self.scan(wpath) - else: - self.created(wpath) - - def process_delete(self, wpath, evt): - if self.ui.debugflag: - self.ui.note(_('%s event: deleted %s\n') % - (self.event_time(), wpath)) - - if evt.mask & inotify.IN_ISDIR: - tree = self.tree.dir(wpath) - todelete = [wfn for wfn, ignore in tree.walk('?')] - for fn in todelete: - self.deletefile(fn, '?') - self.scan(wpath) - else: - self.deleted(wpath) - - def process_modify(self, wpath, evt): - if self.ui.debugflag: - self.ui.note(_('%s event: modified %s\n') % - (self.event_time(), wpath)) - - if not (evt.mask & inotify.IN_ISDIR): - self.modified(wpath) - - def process_unmount(self, evt): - self.ui.warn(_('filesystem containing %s was unmounted\n') % - evt.fullpath) - sys.exit(0) - - def handle_pollevents(self, events): - if self.ui.debugflag: - self.ui.note(_('%s readable: %d bytes\n') % - (self.event_time(), self.threshold.readable())) - if not self.threshold(): - if self.registered: - if self.ui.debugflag: - self.ui.note(_('%s below threshold - unhooking\n') % - (self.event_time())) - self.unregister() - self.timeout = 250 - else: - self.read_events() - - def read_events(self, bufsize=None): - events = self.watcher.read(bufsize) - if self.ui.debugflag: - self.ui.note(_('%s reading %d events\n') % - (self.event_time(), len(events))) - for evt in events: - assert evt.fullpath.startswith(self.wprefix) - wpath = evt.fullpath[self.prefixlen:] - - # paths have been normalized, wpath never ends with a '/' - - if wpath.startswith('.hg/') and evt.mask & inotify.IN_ISDIR: - # ignore subdirectories of .hg/ (merge, patches...) - continue - - if evt.mask & inotify.IN_UNMOUNT: - self.process_unmount(wpath, evt) - elif evt.mask & (inotify.IN_MODIFY | inotify.IN_ATTRIB): - self.process_modify(wpath, evt) - elif evt.mask & (inotify.IN_DELETE | inotify.IN_DELETE_SELF | - inotify.IN_MOVED_FROM): - self.process_delete(wpath, evt) - elif evt.mask & (inotify.IN_CREATE | inotify.IN_MOVED_TO): - self.process_create(wpath, evt) - - self.lastevent.clear() - - def handle_timeout(self): - if not self.registered: - if self.ui.debugflag: - self.ui.note(_('%s hooking back up with %d bytes readable\n') % - (self.event_time(), self.threshold.readable())) - self.read_events(0) - self.register(timeout=None) - - self.timeout = None - - def shutdown(self): - self.watcher.close() - - def debug(self): - """ - Returns a sorted list of relatives paths currently watched, - for debugging purposes. - """ - return sorted(tuple[0][self.prefixlen:] for tuple in self.watcher) - -class server(pollable): +class socketlistener(object): """ Listens for client queries on unix socket inotify.sock """ @@ -718,10 +370,6 @@ raise self.sock.listen(5) self.fileno = self.sock.fileno - self.register(timeout=timeout) - - def handle_timeout(self): - pass def answer_stat_query(self, cs): names = cs.read().split('\0') @@ -730,12 +378,6 @@ self.ui.note(_('answering query for %r\n') % states) - if self.repowatcher.timeout: - # We got a query while a rescan is pending. Make sure we - # rescan before responding, or we could give back a wrong - # answer. - self.repowatcher.handle_timeout() - visited = set() if not names: def genresult(states, tree): @@ -764,11 +406,7 @@ def answer_dbug_query(self): return ['\0'.join(self.repowatcher.debug())] - def handle_pollevents(self, events): - for e in events: - self.handle_pollevent() - - def handle_pollevent(self): + def accept_connection(self): sock, addr = self.sock.accept() cs = common.recvcs(sock) @@ -808,33 +446,12 @@ if err[0] != errno.EPIPE: raise - def shutdown(self): - self.sock.close() - try: - os.unlink(self.sockpath) - if self.realsockpath: - os.unlink(self.realsockpath) - os.rmdir(os.path.dirname(self.realsockpath)) - except OSError, err: - if err.errno != errno.ENOENT: - raise +if sys.platform == 'linux2': + import linuxserver as _server +else: + raise ImportError -class master(object): - def __init__(self, ui, dirstate, root, timeout=None): - self.ui = ui - self.repowatcher = repowatcher(ui, dirstate, root) - self.server = server(ui, root, self.repowatcher, timeout) - - def shutdown(self): - for obj in pollable.instances.itervalues(): - obj.shutdown() - - def run(self): - self.repowatcher.setup() - self.ui.note(_('finished setup\n')) - if os.getenv('TIME_STARTUP'): - sys.exit(0) - pollable.run() +master = _server.master def start(ui, dirstate, root, opts): timeout = opts.get('timeout') diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/keyword.py --- a/hgext/keyword.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/keyword.py Thu Dec 03 01:06:15 2009 +0100 @@ -112,7 +112,8 @@ 'Author': '{author|user}', 'Date': '{date|utcdate}', 'RCSfile': '{file|basename},v', - 'RCSFile': '{file|basename},v', # kept only for backwards compatibility + 'RCSFile': '{file|basename},v', # kept for backwards compatibility + # with hg-keyword 'Source': '{root}/{file},v', 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/patchbomb.py --- a/hgext/patchbomb.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/patchbomb.py Thu Dec 03 01:06:15 2009 +0100 @@ -379,20 +379,21 @@ else: msgs = getpatchmsgs(list(getpatches(revs))) - def getaddrs(opt, prpt, default = None): - addrs = opts.get(opt) or (ui.config('email', opt) or - ui.config('patchbomb', opt) or - prompt(ui, prpt, default)).split(',') - return [mail.addressencode(ui, a.strip(), _charsets, opts.get('test')) - for a in addrs if a.strip()] + def getaddrs(opt, prpt=None, default=None): + if opts.get(opt): + return mail.addrlistencode(ui, opts.get(opt), _charsets, + opts.get('test')) + + addrs = (ui.config('email', opt) or + ui.config('patchbomb', opt) or '') + if not addrs and prpt: + addrs = prompt(ui, prpt, default) + + return mail.addrlistencode(ui, [addrs], _charsets, opts.get('test')) to = getaddrs('to', 'To') cc = getaddrs('cc', 'Cc', '') - - bcc = opts.get('bcc') or (ui.config('email', 'bcc') or - ui.config('patchbomb', 'bcc') or '').split(',') - bcc = [mail.addressencode(ui, a.strip(), _charsets, opts.get('test')) - for a in bcc if a.strip()] + bcc = getaddrs('bcc') ui.write('\n') diff -r 60cefb8b3c85 -r e97dd3a8e8d7 hgext/relink.py --- a/hgext/relink.py Wed Dec 02 14:30:39 2009 +0200 +++ b/hgext/relink.py Thu Dec 03 01:06:15 2009 +0100 @@ -14,25 +14,27 @@ def relink(ui, repo, origin=None, **opts): """recreate hardlinks between two repositories - When repositories are cloned locally, their data files will be hardlinked - so that they only use the space of a single repository. + When repositories are cloned locally, their data files will be + hardlinked so that they only use the space of a single repository. - Unfortunately, subsequent pulls into either repository will break hardlinks - for any files touched by the new changesets, even if both repositories end - up pulling the same changes. + Unfortunately, subsequent pulls into either repository will break + hardlinks for any files touched by the new changesets, even if + both repositories end up pulling the same changes. - Similarly, passing --rev to "hg clone" will fail to use - any hardlinks, falling back to a complete copy of the source repository. + Similarly, passing --rev to "hg clone" will fail to use any + hardlinks, falling back to a complete copy of the source + repository. - This command lets you recreate those hardlinks and reclaim that wasted - space. + This command lets you recreate those hardlinks and reclaim that + wasted space. - This repository will be relinked to share space with ORIGIN, which must be - on the same local disk. If ORIGIN is omitted, looks for "default-relink", - then "default", in [paths]. + This repository will be relinked to share space with ORIGIN, which + must be on the same local disk. If ORIGIN is omitted, looks for + "default-relink", then "default", in [paths]. - Do not attempt any read operations on this repository while the command is - running. (Both repositories will be locked against writes.) + Do not attempt any read operations on this repository while the + command is running. (Both repositories will be locked against + writes.) """ src = hg.repository( cmdutil.remoteui(repo, opts), diff -r 60cefb8b3c85 -r e97dd3a8e8d7 i18n/da.po --- a/i18n/da.po Wed Dec 02 14:30:39 2009 +0200 +++ b/i18n/da.po Thu Dec 03 01:06:15 2009 +0100 @@ -17,8 +17,8 @@ msgstr "" "Project-Id-Version: Mercurial\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-11-10 20:42+0100\n" -"PO-Revision-Date: 2009-11-11 22:54+0100\n" +"POT-Creation-Date: 2009-11-29 20:24+0100\n" +"PO-Revision-Date: 2009-11-29 20:27+0100\n" "Last-Translator: \n" "Language-Team: Danish\n" "MIME-Version: 1.0\n" @@ -135,37 +135,37 @@ "- backout, commit, import, tag: Specify the commit date.\n" "- log, revert, update: Select revision(s) by date.\n" "\n" -"Many date formats are valid. Here are some examples::\n" -"\n" -" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n" -" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n" -" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n" -" \"Dec 6\" (midnight)\n" -" \"13:18\" (today assumed)\n" -" \"3:39\" (3:39AM assumed)\n" -" \"3:39pm\" (15:39)\n" -" \"2006-12-06 13:18:29\" (ISO 8601 format)\n" -" \"2006-12-6 13:18\"\n" -" \"2006-12-6\"\n" -" \"12-6\"\n" -" \"12/6\"\n" -" \"12/6/6\" (Dec 6 2006)\n" -"\n" -"Lastly, there is Mercurial's internal format::\n" -"\n" -" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n" +"Many date formats are valid. Here are some examples:\n" +"\n" +"- ``Wed Dec 6 13:18:29 2006`` (local timezone assumed)\n" +"- ``Dec 6 13:18 -0600`` (year assumed, time offset provided)\n" +"- ``Dec 6 13:18 UTC`` (UTC and GMT are aliases for +0000)\n" +"- ``Dec 6`` (midnight)\n" +"- ``13:18`` (today assumed)\n" +"- ``3:39`` (3:39AM assumed)\n" +"- ``3:39pm`` (15:39)\n" +"- ``2006-12-06 13:18:29`` (ISO 8601 format)\n" +"- ``2006-12-6 13:18``\n" +"- ``2006-12-6``\n" +"- ``12-6``\n" +"- ``12/6``\n" +"- ``12/6/6`` (Dec 6 2006)\n" +"\n" +"Lastly, there is Mercurial's internal format:\n" +"\n" +"- ``1165432709 0`` (Wed Dec 6 13:18:29 2006 UTC)\n" "\n" "This is the internal representation format for dates. unixtime is the\n" "number of seconds since the epoch (1970-01-01 00:00 UTC). offset is\n" "the offset of the local timezone, in seconds west of UTC (negative if\n" "the timezone is east of UTC).\n" "\n" -"The log command also accepts date ranges::\n" -"\n" -" \"<{datetime}\" - at or before a given date/time\n" -" \">{datetime}\" - on or after a given date/time\n" -" \"{datetime} to {datetime}\" - a date range, inclusive\n" -" \"-{days}\" - within a given number of days of today\n" +"The log command also accepts date ranges:\n" +"\n" +"- ``<{datetime}`` - at or before a given date/time\n" +"- ``>{datetime}`` - on or after a given date/time\n" +"- ``{datetime} to {datetime}`` - a date range, inclusive\n" +"- ``-{days}`` - within a given number of days of today\n" msgstr "" "Nogle kommandoer tillader brugeren at specificere en dato, f.eks.:\n" "\n" @@ -174,23 +174,23 @@ "\n" "Der er mange gyldige datoformater. Her er nogle eksempler::\n" "\n" -" \"Wed Dec 6 13:18:29 2006\" (antager lokal tidszone)\n" -" \"Dec 6 13:18 -0600\" (antager år, tidszone er angivet)\n" -" \"Dec 6 13:18 UTC\" (UTC og GMT er aliaser for +0000)\n" -" \"Dec 6\" (midnat)\n" -" \"13:18\" (antager dags dato)\n" -" \"3:39\"\n" -" \"3:39pm\" (15:39)\n" -" \"2006-12-06 13:18:29\" (ISO 8601 format)\n" -" \"2006-12-6 13:18\"\n" -" \"2006-12-6\"\n" -" \"12-6\"\n" -" \"12/6\"\n" -" \"12/6/6\" (6. dec. 2006)\n" +"- ``Wed Dec 6 13:18:29 2006`` (antager lokal tidszone)\n" +"- ``Dec 6 13:18 -0600`` (antager år, tidszone er angivet)\n" +"- ``Dec 6 13:18 UTC`` (UTC og GMT er aliaser for +0000)\n" +"- ``Dec 6`` (midnat)\n" +"- ``13:18`` (antager dags dato)\n" +"- ``3:39``\n" +"- ``3:39pm`` (15:39)\n" +"- ``2006-12-06 13:18:29`` (ISO 8601 format)\n" +"- ``2006-12-6 13:18``\n" +"- ``2006-12-6``\n" +"- ``12-6``\n" +"- ``12/6``\n" +"- ``12/6/6`` (6. dec. 2006)\n" "\n" "Endelig er der Mercurials interne format::\n" "\n" -" \"1165432709 0\" (Ons 6. dec. 13:18:29 2006 UTC)\n" +"- ``1165432709 0`` (Ons 6. dec. 13:18:29 2006 UTC)\n" "\n" "Dette er den interne repræsentation af datoer. unixtime er\n" "antallet af sekunder siden begyndelsen af epoken (1970-01-01 00:00\n" @@ -199,10 +199,10 @@ "\n" "Kommandoen log accepterer også datointervaller::\n" "\n" -" \"<{date}\" - på eller før den angivne dato/tidspunkt\n" -" \">{date}\" - på eller efter den angivne dato/tidspunkt\n" -" \"{date} to {date}\" - et datointerval, inklusiv endepunkterne\n" -" \"-{days}\" - indenfor et angivet antal dage, fra dags dato\n" +"- ``<{date}`` - på eller før den angivne dato/tidspunkt\n" +"- ``>{date}`` - på eller efter den angivne dato/tidspunkt\n" +"- ``{date} to {date}`` - et datointerval, inklusiv endepunkterne\n" +"- ``-{days}`` - indenfor et angivet antal dage, fra dags dato\n" msgid "" "Mercurial's default format for showing changes between two versions of\n" @@ -1813,6 +1813,11 @@ msgid "Mercurial failed to run itself, check hg executable is in PATH" msgstr "Mercurial kunne ikke køre sig selv, kontroller om hg er i PATH" +msgid "" +"svn: cannot probe remote repository, assume it could be a subversion " +"repository. Use --source-type if you know better.\n" +msgstr "" + msgid "Subversion python bindings could not be loaded" msgstr "Subversion python bindingerne kunne ikke indlæses" @@ -1981,15 +1986,14 @@ msgid "" "use %(path)s to diff repository (or selected files)\n" "\n" -" Show differences between revisions for the specified files, using the\n" -" %(path)s program.\n" -"\n" -" When two revision arguments are given, then changes are shown between\n" -" those revisions. If only one revision is specified then that revision " -"is\n" -" compared to the working directory, and, when no revisions are " -"specified,\n" -" the working directory files are compared to its parent." +" Show differences between revisions for the specified files, using\n" +" the %(path)s program.\n" +"\n" +" When two revision arguments are given, then changes are shown\n" +" between those revisions. If only one revision is specified then\n" +" that revision is compared to the working directory, and, when no\n" +" revisions are specified, the working directory files are compared\n" +" to its parent." msgstr "" #, python-format @@ -2449,23 +2453,23 @@ msgid "hg inserve [OPTION]..." msgstr "hg inserve [TILVALG]..." -msgid "(found dead inotify server socket; removing it)\n" -msgstr "(fandt død inotify server sokkel; fjerner den)\n" - -#, python-format -msgid "could not start inotify server: %s\n" -msgstr "kunne ikke starte inotify server: %s\n" - -#, python-format -msgid "could not talk to new inotify server: %s\n" -msgstr "kunne ikke snakke med ny inotify server: %s\n" - -#, python-format -msgid "failed to contact inotify server: %s\n" -msgstr "kontakt med inotify server miskykkedes: %s\n" - -msgid "received empty answer from inotify server" -msgstr "modtog tomt svar fra inotify server" +msgid "inotify-client: found dead inotify server socket; removing it\n" +msgstr "inotify-klient: fandt død inotify server sokkel; fjerner den\n" + +#, python-format +msgid "inotify-client: could not start inotify server: %s\n" +msgstr "inotify-klient: kunne ikke starte inotify server: %s\n" + +#, python-format +msgid "inotify-client: could not talk to new inotify server: %s\n" +msgstr "inotify-klient: kunne ikke snakke med ny inotify server: %s\n" + +#, python-format +msgid "inotify-client: failed to contact inotify server: %s\n" +msgstr "inotify-klient: kontakt med inotify server mislykkedes: %s\n" + +msgid "inotify-client: received empty answer from inotify server" +msgstr "inotify-klient: modtog tomt svar fra inotify server" #, python-format msgid "(inotify: received response from incompatible server version %d)\n" @@ -2521,21 +2525,6 @@ msgstr "overvåger kataloger under %r\n" #, python-format -msgid "status: %r %s -> %s\n" -msgstr "status: %r %s -> %s\n" - -#, python-format -msgid "%s dirstate reload\n" -msgstr "%s genindlæsning af dirstate\n" - -#, python-format -msgid "%s end dirstate reload\n" -msgstr "%s genindlæsning af dirstate afsluttet\n" - -msgid "rescanning due to .hgignore change\n" -msgstr "genskanner på grund af ændring af .hgignore\n" - -#, python-format msgid "%s event: created %s\n" msgstr "%s hændelse: oprettede %s\n" @@ -2567,9 +2556,23 @@ msgid "%s hooking back up with %d bytes readable\n" msgstr "" -#, python-format -msgid "could not start server: %s" -msgstr "kunne ikke starte server: %s" +msgid "finished setup\n" +msgstr "afsluttede opsætning\n" + +#, python-format +msgid "status: %r %s -> %s\n" +msgstr "status: %r %s -> %s\n" + +msgid "rescanning due to .hgignore change\n" +msgstr "genskanner på grund af ændring af .hgignore\n" + +msgid "cannot start: socket is already bound" +msgstr "" + +msgid "" +"cannot start: tried linking .hg/inotify.sock to a temporary socket but .hg/" +"inotify.sock already exists" +msgstr "" #, python-format msgid "answering query for %r\n" @@ -2583,9 +2586,6 @@ msgid "unrecognized query type: %s\n" msgstr "genkendte ikke forespørgselstype: %s\n" -msgid "finished setup\n" -msgstr "afsluttede opsætning\n" - msgid "" "expand expressions into changelog and summaries\n" "\n" @@ -3507,7 +3507,8 @@ " With arguments, set guards for the named patch.\n" " NOTE: Specifying negative guards now requires '--'.\n" "\n" -" To set guards on another patch:\n" +" To set guards on another patch::\n" +"\n" " hg qguard -- other.patch +2.6.17 -stable\n" " " msgstr "" @@ -3640,7 +3641,7 @@ " qselect to tell mq which guards to use. A patch will be pushed if\n" " it has no guards or any positive guards match the currently\n" " selected guard, but will not be pushed if any negative guards\n" -" match the current guard. For example:\n" +" match the current guard. For example::\n" "\n" " qguard foo.patch -stable (negative guard)\n" " qguard bar.patch +stable (positive guard)\n" @@ -3708,11 +3709,14 @@ #, python-format msgid "number of unguarded, unapplied patches has changed from %d to %d\n" -msgstr "antallet af ufiltrerede og ikke-anvendte rettelser har ændret sig fra %dtil %d\n" +msgstr "" +"antallet af ufiltrerede og ikke-anvendte rettelser har ændret sig fra %dtil %" +"d\n" #, python-format msgid "number of guarded, applied patches has changed from %d to %d\n" -msgstr "antallet af filtrerede og anvendte rettelser har ændret sig fra %d til %d\n" +msgstr "" +"antallet af filtrerede og anvendte rettelser har ændret sig fra %d til %d\n" msgid "guards in series file:\n" msgstr "filtre i seriefilen:\n" @@ -4132,10 +4136,13 @@ " ignore = version, help, update\n" "\n" "You can also enable the pager only for certain commands using\n" -"pager.attend::\n" +"pager.attend. Below is the default list of commands to be paged::\n" "\n" " [pager]\n" -" attend = log\n" +" attend = annotate, cat, diff, export, glog, log, qdiff\n" +"\n" +"Setting pager.attend to an empty value will cause all commands to be\n" +"paged.\n" "\n" "If pager.attend is present, pager.ignore will be ignored.\n" "\n" @@ -4661,9 +4668,6 @@ msgid " and " msgstr " og " -msgid "y" -msgstr "j" - #, python-format msgid "record this change to %r?" msgstr "optag denne ændring i %r?" @@ -4744,32 +4748,27 @@ msgid "" "recreate hardlinks between two repositories\n" "\n" -" When repositories are cloned locally, their data files will be " -"hardlinked\n" -" so that they only use the space of a single repository.\n" -"\n" -" Unfortunately, subsequent pulls into either repository will break " -"hardlinks\n" -" for any files touched by the new changesets, even if both repositories " -"end\n" -" up pulling the same changes.\n" -"\n" -" Similarly, passing --rev to \"hg clone\" will fail to use\n" -" any hardlinks, falling back to a complete copy of the source " -"repository.\n" -"\n" -" This command lets you recreate those hardlinks and reclaim that wasted\n" -" space.\n" -"\n" -" This repository will be relinked to share space with ORIGIN, which must " -"be\n" -" on the same local disk. If ORIGIN is omitted, looks for \"default-relink" -"\",\n" -" then \"default\", in [paths].\n" -"\n" -" Do not attempt any read operations on this repository while the command " -"is\n" -" running. (Both repositories will be locked against writes.)\n" +" When repositories are cloned locally, their data files will be\n" +" hardlinked so that they only use the space of a single repository.\n" +"\n" +" Unfortunately, subsequent pulls into either repository will break\n" +" hardlinks for any files touched by the new changesets, even if\n" +" both repositories end up pulling the same changes.\n" +"\n" +" Similarly, passing --rev to \"hg clone\" will fail to use any\n" +" hardlinks, falling back to a complete copy of the source\n" +" repository.\n" +"\n" +" This command lets you recreate those hardlinks and reclaim that\n" +" wasted space.\n" +"\n" +" This repository will be relinked to share space with ORIGIN, which\n" +" must be on the same local disk. If ORIGIN is omitted, looks for\n" +" \"default-relink\", then \"default\", in [paths].\n" +"\n" +" Do not attempt any read operations on this repository while the\n" +" command is running. (Both repositories will be locked against\n" +" writes.)\n" " " msgstr "" @@ -5458,14 +5457,14 @@ " directory; use -r/--rev to specify a different revision.\n" "\n" " To specify the type of archive to create, use -t/--type. Valid\n" -" types are::\n" -"\n" -" \"files\" (default): a directory full of files\n" -" \"tar\": tar archive, uncompressed\n" -" \"tbz2\": tar archive, compressed using bzip2\n" -" \"tgz\": tar archive, compressed using gzip\n" -" \"uzip\": zip archive, uncompressed\n" -" \"zip\": zip archive, compressed using deflate\n" +" types are:\n" +"\n" +" :``files``: a directory full of files (default)\n" +" :``tar``: tar archive, uncompressed\n" +" :``tbz2``: tar archive, compressed using bzip2\n" +" :``tgz``: tar archive, compressed using gzip\n" +" :``uzip``: zip archive, uncompressed\n" +" :``zip``: zip archive, compressed using deflate\n" "\n" " The exact name of the destination archive or directory is given\n" " using a format string; see 'hg help export' for details.\n" @@ -5742,11 +5741,11 @@ "\n" " Output may be to a file, in which case the name of the file is\n" " given using a format string. The formatting rules are the same as\n" -" for the export command, with the following additions::\n" -"\n" -" %s basename of file being printed\n" -" %d dirname of file being printed, or '.' if in repository root\n" -" %p root-relative path name of file being printed\n" +" for the export command, with the following additions:\n" +"\n" +" :``%s``: basename of file being printed\n" +" :``%d``: dirname of file being printed, or '.' if in repository root\n" +" :``%p``: root-relative path name of file being printed\n" " " msgstr "" "udskriv den aktuelle eller en given revision af filer\n" @@ -5758,12 +5757,12 @@ "\n" " Output kan gemmes i en fil hvis navn angives med et formatstreng.\n" " Reglerne for formatteringen er de samme som for export-kommandoen\n" -" med følgende tilføjelser::\n" -"\n" -" %s grundnavn for filen som udskrives\n" -" %d katalognavn for filen som blvier udskrevet\n" -" eller '.' hvis filen er i katalogets rod\n" -" %p rod-relativ sti for filen som bliver udkrevet\n" +" med følgende tilføjelser:\n" +"\n" +" :``%s``: grundnavn for filen som udskrives\n" +" :``%d``: katalognavn for filen som blvier udskrevet\n" +" eller '.' hvis filen er i katalogets rod\n" +" :``%p``: rod-relativ sti for filen som bliver udkrevet\n" " " msgid "" @@ -5788,9 +5787,9 @@ " will be the null changeset). Otherwise, clone will initially check\n" " out (in order of precedence):\n" "\n" -" a) the changeset, tag or branch specified with -u/--updaterev\n" -" b) the changeset, tag or branch given with the first -r/--rev\n" -" c) the head of the default branch\n" +" a) the changeset, tag or branch specified with -u/--updaterev\n" +" b) the changeset, tag or branch given with the first -r/--rev\n" +" c) the head of the default branch\n" "\n" " Use 'hg clone -u . src dst' to checkout the source repository's\n" " parent changeset (applicable for local source repositories only).\n" @@ -5799,8 +5798,8 @@ " by listing each changeset (tag, or branch name) with -r/--rev.\n" " If -r/--rev is used, the cloned repository will contain only a subset\n" " of the changesets of the source repository. Only the set of changesets\n" -" defined by all -r/--rev options (including their direct and indirect\n" -" parent changesets) will be pulled into the destination repository.\n" +" defined by all -r/--rev options (including all their ancestors)\n" +" will be pulled into the destination repository.\n" " No subsequent changesets (including subsequent tags) will be present\n" " in the destination.\n" "\n" @@ -5848,11 +5847,11 @@ " et depot (.hg) og intet arbejdskatalog (arbejdskatalogets forælder\n" " er sat til nul revisionen). Ellers vil clone kommandoen hente\n" "\n" -" a) ændringen, mærkaten eller grenen specificeret med\n" -" -u/--updaterev\n" -" b) ændringen, mærkaten eller grenen angivet med den første\n" -" -r/--rev\n" -" c) hovedet af default grenen\n" +" a) ændringen, mærkaten eller grenen specificeret med\n" +" -u/--updaterev\n" +" b) ændringen, mærkaten eller grenen angivet med den første\n" +" -r/--rev\n" +" c) hovedet af default grenen\n" "\n" " Brug 'hg clone -u . kilde destination' for at hente ændringen i\n" " kildedepotet ud i destinations depotet (kan kun anvendes ved\n" @@ -5863,10 +5862,9 @@ " grennavn) med -r/--rev. Hvis -r/--rev tilvalget bruges, så vil det\n" " klonede depot kun indeholde en delmængde af ændringerne i\n" " kildedepotet. Det er kun mængden af ændringer defineret af alle\n" -" -r/--rev tilvalgene (inklusiv deres direkte og indirekte forfædre)\n" -" som vil blive hevet ind i destinationsdepotet. Ingen efterfølgende\n" -" revisioner (inklusiv efterfølgende mærkater) vil findes i\n" -" destinationen.\n" +" -r/--rev tilvalgene (inklusiv alle deres forfædre) som vil blive\n" +" hevet ind i destinationsdepotet. Ingen efterfølgende revisioner\n" +" (inklusiv efterfølgende mærkater) vil findes i destinationen.\n" "\n" " Brug af -r/--rev (eller 'clone kilde#rev destination') medfører\n" " --pull, selv ved lokale depoter.\n" @@ -6193,16 +6191,16 @@ " first parent only.\n" "\n" " Output may be to a file, in which case the name of the file is\n" -" given using a format string. The formatting rules are as follows::\n" -"\n" -" %% literal \"%\" character\n" -" %H changeset hash (40 bytes of hexadecimal)\n" -" %N number of patches being generated\n" -" %R changeset revision number\n" -" %b basename of the exporting repository\n" -" %h short-form changeset hash (12 bytes of hexadecimal)\n" -" %n zero-padded sequence number, starting at 1\n" -" %r zero-padded changeset revision number\n" +" given using a format string. The formatting rules are as follows:\n" +"\n" +" :``%%``: literal \"%\" character\n" +" :``%H``: changeset hash (40 bytes of hexadecimal)\n" +" :``%N``: number of patches being generated\n" +" :``%R``: changeset revision number\n" +" :``%b``: basename of the exporting repository\n" +" :``%h``: short-form changeset hash (12 bytes of hexadecimal)\n" +" :``%n``: zero-padded sequence number, starting at 1\n" +" :``%r``: zero-padded changeset revision number\n" "\n" " Without the -a/--text option, export will avoid generating diffs\n" " of files it detects as binary. With -a, export will generate a\n" @@ -6230,14 +6228,14 @@ " Uddata kan gemmes i en fil, og filnavnet er givet ved en\n" " format-streng. Formatteringsreglerne er som følger::\n" "\n" -" %% litteral % tegn\n" -" %H ændringshash (40 byte heksadecimal)\n" -" %N antallet af rettelser som bliver genereret\n" -" %R revisionnummer for ændringen\n" -" %b grundnavn for det eksporterede depot\n" -" %h kortform ændringshash (12 byte heksadecimal)\n" -" %n nul-fyldt sekvensnummer, startende ved 1\n" -" %r nul-fyldt revisionsnummer for ændringen\n" +" :``%%``: litteral \"%\" tegn\n" +" :``%H``: ændringshash (40 byte heksadecimal)\n" +" :``%N``: antallet af rettelser som bliver genereret\n" +" :``%R``: revisionnummer for ændringen\n" +" :``%b``: grundnavn for det eksporterede depot\n" +" :``%h``: kortform ændringshash (12 byte heksadecimal)\n" +" :``%n``: nul-fyldt sekvensnummer, startende ved 1\n" +" :``%r``: nul-fyldt revisionsnummer for ændringen\n" "\n" " Uden -a/--text tilvalget vil annotate undgå at behandle filer som\n" " den detekterer som binære. Med -a vil annotate generere en\n" @@ -6408,9 +6406,6 @@ msgid "no commands defined\n" msgstr "ingen kommandoer defineret\n" -msgid "enabled extensions:" -msgstr "aktiverede udvidelser:" - msgid "no help text available" msgstr "ingen hjælpetekst tilgængelig" @@ -6432,6 +6427,9 @@ "basale kommandoer:\n" "\n" +msgid "enabled extensions:" +msgstr "aktiverede udvidelser:" + msgid "DEPRECATED" msgstr "" @@ -7047,13 +7045,13 @@ " Transactions are used to encapsulate the effects of all commands\n" " that create new changesets or propagate existing changesets into a\n" " repository. For example, the following commands are transactional,\n" -" and their effects can be rolled back::\n" -"\n" -" commit\n" -" import\n" -" pull\n" -" push (with this repository as destination)\n" -" unbundle\n" +" and their effects can be rolled back:\n" +"\n" +" - commit\n" +" - import\n" +" - pull\n" +" - push (with this repository as destination)\n" +" - unbundle\n" "\n" " This command is not intended for use on public repositories. Once\n" " changes are visible for pull by other users, rolling a transaction\n" @@ -7352,13 +7350,13 @@ " The following rules apply when the working directory contains\n" " uncommitted changes:\n" "\n" -" 1. If neither -c/--check nor -C/--clean is specified, uncommitted\n" -" changes are merged into the requested changeset, and the merged " -"result\n" -" is left uncommitted. Updating and merging will occur only if the\n" -" requested changeset is an ancestor or descendant of the parent\n" -" changeset. Otherwise, the update is aborted and the uncommitted " -"changes\n" +" 1. If neither -c/--check nor -C/--clean is specified, and if\n" +" the requested changeset is an ancestor or descendant of\n" +" the working directory's parent, the uncommitted changes\n" +" are merged into the requested changeset and the merged\n" +" result is left uncommitted. If the requested changeset is\n" +" not an ancestor or descendant (that is, it is on another\n" +" branch), the update is aborted and the uncommitted changes\n" " are preserved.\n" "\n" " 2. With the -c/--check option, the update is aborted and the\n" @@ -7388,13 +7386,14 @@ " De følgende regler gælder når arbejdskataloget indeholder\n" " udeponerede ændringer:\n" "\n" -" 1. Hvis hverken -c/--check eler -C/--clean er angivet, så bliver\n" -" udeponerede ændringer føjet ind i den ønskede ændring og det\n" -" sammenføjne resultat bliver efterlad udeponeret. Opdateringen\n" -" eller sammenføjningen vil kun finde sted hvis den ønskede\n" -" ændring er forfar til eller nedstammer fra forældreændringen.\n" -" Ellers vil opdateringen blive afbrudt og de udeponerede\n" -" ændringer bliver bevaret.\n" +" 1. Hvis hverken -c/--check eller -C/--clean er angivet og hvis den\n" +" ønskede ændring er en forfar til eller nedstammer fra\n" +" arbejdskatalogets forældre, så bliver udeponerede ændringer\n" +" føjet ind i den ønskede ændring og det sammenføjne resultat\n" +" bliver efterlad udeponeret. Hvis den ønskede ændring ikke er\n" +" forfar til eller nedstammer fra forældreændringen (det vil\n" +" sige, den er på en anden gren), så vil opdateringen blive\n" +" afbrudt og de udeponerede ændringer bliver bevaret.\n" "\n" " 2. Med -c/--check tilvalget vil opdateringen blive afbrudt og de\n" " udeponerede ændringer bliver bevaret.\n" @@ -7696,8 +7695,8 @@ msgid "revision, tag or branch to check out" msgstr "revision, mærkat eller gren som skal hentes ud" -msgid "a changeset you would like to have after cloning" -msgstr "en ændringer du gerne vil have efter kloningen" +msgid "clone only the specified revisions and ancestors" +msgstr "klon kun de specificerede revisioner og deres forfædre" msgid "[OPTION]... SOURCE [DEST]" msgstr "[TILVALG]... KILDE [MÅL]" @@ -8266,6 +8265,16 @@ msgstr "ingen definition for alias '%s'\n" #, python-format +msgid "" +"alias for: hg %s\n" +"\n" +"%s" +msgstr "" +"alias for: hg %s\n" +"\n" +"%s" + +#, python-format msgid "alias '%s' resolves to unknown command '%s'\n" msgstr "alias '%s' oversætter til ukendt kommando '%s'\n" @@ -8274,8 +8283,8 @@ msgstr "alias '%s' oversætter til tvetydig kommando '%s'\n" #, python-format -msgid "malformed --config option: %s" -msgstr "misdannet --config tilvalg: %s" +msgid "malformed --config option: %r (use --config section.name=value)" +msgstr "misdannet --config tilvalg: %r (brug --config sektion.navn=værdi)" #, python-format msgid "extension '%s' overrides commands: %s\n" @@ -8490,6 +8499,12 @@ msgid "%s hook is invalid (\"%s\" not in a module)" msgstr "" +msgid "exception from first failed import attempt:\n" +msgstr "fejltekst fra første fejlede import-forsøg:\n" + +msgid "exception from second failed import attempt:\n" +msgstr "fejltekst fra andet fejlede import-forsøg:\n" + #, python-format msgid "%s hook is invalid (import of \"%s\" failed)" msgstr "" @@ -8632,7 +8647,7 @@ msgstr "ukendt revision '%s'" msgid "abandoned transaction found - run hg recover" -msgstr "" +msgstr "fandt en efterladt transaktion - kør hg recover" msgid "rolling back interrupted transaction\n" msgstr "ruller afbrudt transaktion tilbage\n" @@ -8665,6 +8680,8 @@ msgid "cannot partially commit a merge (do not specify files or patterns)" msgstr "" +"kan ikke deponere en sammenføjning partielt (undgå at specificere filer " +"eller mønstre)" msgid "file not found!" msgstr "filen blev ikke fundet!" @@ -8683,6 +8700,10 @@ msgstr "deponerer underdepot %s\n" #, python-format +msgid "note: commit message saved in %s\n" +msgstr "bemærk: deponeringsbesked er gemt i %s\n" + +#, python-format msgid "trouble committing %s!\n" msgstr "problem ved deponering %s!\n" @@ -8695,6 +8716,8 @@ "%s: files over 10MB may cause memory and performance problems\n" "(use 'hg revert %s' to unadd the file)\n" msgstr "" +"%s: filer på over 10 MB kan skabe hukommelses- og ydelsesproblemer\n" +"(brug 'hg revert %s' for at u-tilføje filen)\n" #, python-format msgid "%s not added: only files and symlinks supported currently\n" @@ -8756,7 +8779,7 @@ msgstr "(glemte du at sammenføje? brug push -f for at gennemtvinge)\n" msgid "note: unsynced remote changes!\n" -msgstr "" +msgstr "bemærk: usynkroniserede ændringer i fjernsystemet!\n" #, python-format msgid "%d changesets found\n" @@ -8799,10 +8822,10 @@ msgstr "låsning af fjerndepotet fejlede" msgid "the server sent an unknown error code" -msgstr "" +msgstr "serveren sendte en ukendt fejlkode" msgid "streaming all changes\n" -msgstr "" +msgstr "streamer alle ændringer\n" #, python-format msgid "%d files to transfer, %s of data\n" @@ -8817,7 +8840,7 @@ #, python-format msgid "sending mail: smtp host %s, port %s\n" -msgstr "" +msgstr "sender mail: smtp host %s, port %s\n" msgid "can't use TLS: Python SSL support not installed" msgstr "kan ikke bruge TLS: Python SSL support er ikke installeret" @@ -8842,7 +8865,7 @@ #, python-format msgid "ignoring invalid sendcharset: %s\n" -msgstr "" +msgstr "ignorerer ugyldigt sendcharset: %s\n" #, python-format msgid "invalid email address: %s" diff -r 60cefb8b3c85 -r e97dd3a8e8d7 i18n/sv.po --- a/i18n/sv.po Wed Dec 02 14:30:39 2009 +0200 +++ b/i18n/sv.po Thu Dec 03 01:06:15 2009 +0100 @@ -13,8 +13,8 @@ msgstr "" "Project-Id-Version: Mercurial\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-11-10 20:01+0100\n" -"PO-Revision-Date: 2009-11-10 20:06+0100\n" +"POT-Creation-Date: 2009-11-22 19:02+0100\n" +"PO-Revision-Date: 2009-11-22 19:37+0100\n" "Last-Translator: Jens Bäckman \n" "Language-Team: Swedish\n" "MIME-Version: 1.0\n" @@ -85,6 +85,43 @@ "- on Unix-like systems: ``man hgrc``\n" "- online: http://www.selenic.com/mercurial/hgrc.5.html\n" msgstr "" +"Mercurial läser konfigurationsdata från flera filer, om de existerar.\n" +"Nedan listar vi den mest specifika filen först.\n" +"\n" +"Under Windows läses dessa konfigurationsfiler:\n" +"\n" +"- ``\\.hg\\hgrc``\n" +"- ``%USERPROFILE%\\.hgrc``\n" +"- ``%USERPROFILE%\\Mercurial.ini``\n" +"- ``%HOME%\\.hgrc``\n" +"- ``%HOME%\\Mercurial.ini``\n" +"- ``C:\\Mercurial\\Mercurial.ini``\n" +"- ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Mercurial``\n" +"- ``\\Mercurial.ini``\n" +"\n" +"Under Unix läses dessa filer:\n" +"\n" +"- ``/.hg/hgrc``\n" +"- ``$HOME/.hgrc``\n" +"- ``/etc/mercurial/hgrc``\n" +"- ``/etc/mercurial/hgrc.d/*.rc``\n" +"- ``/etc/mercurial/hgrc``\n" +"- ``/etc/mercurial/hgrc.d/*.rc``\n" +"\n" +"Konfigurationsfilerna för Mercurial använder ett enkelt ini-filformat. En\n" +"file består av sektioner, som inleds av en rubrik (ex ``[sektion]``) och\n" +"följs av rader med ``namn = värde``::\n" +"\n" +" [ui]\n" +" username = Förnamn Efternamn \n" +" verbose = True\n" +"\n" +"Raderna ovanför refereras till som ``ui.username`` och\n" +"``ui.verbose``. Läs man-sidan för hgrc för en full beskrivning av alla\n" +"möjliga konfigurationsvärden:\n" +"\n" +"- under Unix-liknande system: ``man hgrc``\n" +"- online: http://www.selenic.com/mercurial/hgrc.5.html\n" msgid "" "Some commands allow the user to specify a date, e.g.:\n" @@ -92,37 +129,37 @@ "- backout, commit, import, tag: Specify the commit date.\n" "- log, revert, update: Select revision(s) by date.\n" "\n" -"Many date formats are valid. Here are some examples::\n" -"\n" -" \"Wed Dec 6 13:18:29 2006\" (local timezone assumed)\n" -" \"Dec 6 13:18 -0600\" (year assumed, time offset provided)\n" -" \"Dec 6 13:18 UTC\" (UTC and GMT are aliases for +0000)\n" -" \"Dec 6\" (midnight)\n" -" \"13:18\" (today assumed)\n" -" \"3:39\" (3:39AM assumed)\n" -" \"3:39pm\" (15:39)\n" -" \"2006-12-06 13:18:29\" (ISO 8601 format)\n" -" \"2006-12-6 13:18\"\n" -" \"2006-12-6\"\n" -" \"12-6\"\n" -" \"12/6\"\n" -" \"12/6/6\" (Dec 6 2006)\n" -"\n" -"Lastly, there is Mercurial's internal format::\n" -"\n" -" \"1165432709 0\" (Wed Dec 6 13:18:29 2006 UTC)\n" +"Many date formats are valid. Here are some examples:\n" +"\n" +"- ``Wed Dec 6 13:18:29 2006`` (local timezone assumed)\n" +"- ``Dec 6 13:18 -0600`` (year assumed, time offset provided)\n" +"- ``Dec 6 13:18 UTC`` (UTC and GMT are aliases for +0000)\n" +"- ``Dec 6`` (midnight)\n" +"- ``13:18`` (today assumed)\n" +"- ``3:39`` (3:39AM assumed)\n" +"- ``3:39pm`` (15:39)\n" +"- ``2006-12-06 13:18:29`` (ISO 8601 format)\n" +"- ``2006-12-6 13:18``\n" +"- ``2006-12-6``\n" +"- ``12-6``\n" +"- ``12/6``\n" +"- ``12/6/6`` (Dec 6 2006)\n" +"\n" +"Lastly, there is Mercurial's internal format:\n" +"\n" +"- ``1165432709 0`` (Wed Dec 6 13:18:29 2006 UTC)\n" "\n" "This is the internal representation format for dates. unixtime is the\n" "number of seconds since the epoch (1970-01-01 00:00 UTC). offset is\n" "the offset of the local timezone, in seconds west of UTC (negative if\n" "the timezone is east of UTC).\n" "\n" -"The log command also accepts date ranges::\n" -"\n" -" \"<{datetime}\" - at or before a given date/time\n" -" \">{datetime}\" - on or after a given date/time\n" -" \"{datetime} to {datetime}\" - a date range, inclusive\n" -" \"-{days}\" - within a given number of days of today\n" +"The log command also accepts date ranges:\n" +"\n" +"- ``<{datetime}`` - at or before a given date/time\n" +"- ``>{datetime}`` - on or after a given date/time\n" +"- ``{datetime} to {datetime}`` - a date range, inclusive\n" +"- ``-{days}`` - within a given number of days of today\n" msgstr "" msgid "" @@ -1599,6 +1636,11 @@ msgid "Mercurial failed to run itself, check hg executable is in PATH" msgstr "" +msgid "" +"svn: cannot probe remote repository, assume it could be a subversion " +"repository. Use --source-type if you know better.\n" +msgstr "" + msgid "Subversion python bindings could not be loaded" msgstr "" @@ -3118,7 +3160,8 @@ " With arguments, set guards for the named patch.\n" " NOTE: Specifying negative guards now requires '--'.\n" "\n" -" To set guards on another patch:\n" +" To set guards on another patch::\n" +"\n" " hg qguard -- other.patch +2.6.17 -stable\n" " " msgstr "" @@ -3213,7 +3256,7 @@ " qselect to tell mq which guards to use. A patch will be pushed if\n" " it has no guards or any positive guards match the currently\n" " selected guard, but will not be pushed if any negative guards\n" -" match the current guard. For example:\n" +" match the current guard. For example::\n" "\n" " qguard foo.patch -stable (negative guard)\n" " qguard bar.patch +stable (positive guard)\n" @@ -3663,10 +3706,13 @@ " ignore = version, help, update\n" "\n" "You can also enable the pager only for certain commands using\n" -"pager.attend::\n" +"pager.attend. Below is the default list of commands to be paged::\n" "\n" " [pager]\n" -" attend = log\n" +" attend = annotate, cat, diff, export, glog, log, qdiff\n" +"\n" +"Setting pager.attend to an empty value will cause all commands to be\n" +"paged.\n" "\n" "If pager.attend is present, pager.ignore will be ignored.\n" "\n" @@ -4161,9 +4207,6 @@ msgid " and " msgstr "" -msgid "y" -msgstr "" - #, python-format msgid "record this change to %r?" msgstr "" @@ -4222,32 +4265,27 @@ msgid "" "recreate hardlinks between two repositories\n" "\n" -" When repositories are cloned locally, their data files will be " -"hardlinked\n" -" so that they only use the space of a single repository.\n" -"\n" -" Unfortunately, subsequent pulls into either repository will break " -"hardlinks\n" -" for any files touched by the new changesets, even if both repositories " -"end\n" -" up pulling the same changes.\n" -"\n" -" Similarly, passing --rev to \"hg clone\" will fail to use\n" -" any hardlinks, falling back to a complete copy of the source " -"repository.\n" -"\n" -" This command lets you recreate those hardlinks and reclaim that wasted\n" -" space.\n" -"\n" -" This repository will be relinked to share space with ORIGIN, which must " -"be\n" -" on the same local disk. If ORIGIN is omitted, looks for \"default-relink" -"\",\n" -" then \"default\", in [paths].\n" -"\n" -" Do not attempt any read operations on this repository while the command " -"is\n" -" running. (Both repositories will be locked against writes.)\n" +" When repositories are cloned locally, their data files will be\n" +" hardlinked so that they only use the space of a single repository.\n" +"\n" +" Unfortunately, subsequent pulls into either repository will break\n" +" hardlinks for any files touched by the new changesets, even if\n" +" both repositories end up pulling the same changes.\n" +"\n" +" Similarly, passing --rev to \"hg clone\" will fail to use any\n" +" hardlinks, falling back to a complete copy of the source\n" +" repository.\n" +"\n" +" This command lets you recreate those hardlinks and reclaim that\n" +" wasted space.\n" +"\n" +" This repository will be relinked to share space with ORIGIN, which\n" +" must be on the same local disk. If ORIGIN is omitted, looks for\n" +" \"default-relink\", then \"default\", in [paths].\n" +"\n" +" Do not attempt any read operations on this repository while the\n" +" command is running. (Both repositories will be locked against\n" +" writes.)\n" " " msgstr "" @@ -4863,12 +4901,27 @@ " can be expensive.\n" " " msgstr "" +"lägg till alla nya nya filer, radera alla saknade filer\n" +"\n" +" Lägg till alla nya filer och radera alla saknade filer från arkivet.\n" +"\n" +" Nya filer ignoreras om de överrensstämmer något av mönstren i\n" +" .hgignore. Precis som med add, kommer ändringarna att träda i kraft vid\n" +" nästa arkivering.\n" +"\n" +" Använd flaggan -s/--similarity för att upptäcka omdöpta filer. Med en\n" +" parameter större än 0, kommer varje borttagen fil att jämföras med\n" +" varje tillagd fil och lagrar de som är tillräckligt lika som ett\n" +" namnbyte. Flaggan tar ett procentvärde mellan 0 (deaktiverad) och 100\n" +" (filer måste vara identiska) som parameter. Att upptäcka omdöpta filer\n" +" på det här sättet kan ta lång tid.\n" +" " msgid "similarity must be a number" -msgstr "" +msgstr "likhet måste vara ett nummer" msgid "similarity must be between 0 and 100" -msgstr "" +msgstr "likhet måste vara mellan 0 och 100" msgid "" "show changeset information by line for each file\n" @@ -4914,14 +4967,14 @@ " directory; use -r/--rev to specify a different revision.\n" "\n" " To specify the type of archive to create, use -t/--type. Valid\n" -" types are::\n" -"\n" -" \"files\" (default): a directory full of files\n" -" \"tar\": tar archive, uncompressed\n" -" \"tbz2\": tar archive, compressed using bzip2\n" -" \"tgz\": tar archive, compressed using gzip\n" -" \"uzip\": zip archive, uncompressed\n" -" \"zip\": zip archive, compressed using deflate\n" +" types are:\n" +"\n" +" :``files``: a directory full of files (default)\n" +" :``tar``: tar archive, uncompressed\n" +" :``tbz2``: tar archive, compressed using bzip2\n" +" :``tgz``: tar archive, compressed using gzip\n" +" :``uzip``: zip archive, uncompressed\n" +" :``zip``: zip archive, compressed using deflate\n" "\n" " The exact name of the destination archive or directory is given\n" " using a format string; see 'hg help export' for details.\n" @@ -4932,15 +4985,37 @@ " removed.\n" " " msgstr "" +"skapa ett icke versionshanterat arkiv från en arkivresision\n" +"\n" +" Som standard används revisonen för arbetskatalogens förälder; använd\n" +" -r/--rev för att specificera en annan revision.\n" +"\n" +" För att definiera vilken typ av arkiv som ska skapas, använd -t/--type.\n" +" Giltiga typer är::\n" +"\n" +" :``files``: en katalog fylld med filer (standard)\n" +" :``tar``: tar-arkiv, okomprimerad\n" +" :``tbz2``: tar-arkiv, komprimerad med bzip2\n" +" :``tgz``: tar-arkiv, komprimerad med gzip\n" +" :``uzip``: zip-arkiv, okomprimerad\n" +" :``zip``: zip-arkiv, komprimerad med deflate\n" +"\n" +" Det exakta namnet på destinationsarkivet eller -katalogen anges med en\n" +" formatsträng; se 'hg help export' för detaljer.\n" +"\n" +" Varje fil som läggs till en arkivfil har ett katalogprefix. Använd\n" +" -p/--prefix för att specificera en formatsträn för prefixet. Som\n" +" standard används basnamnet för arkivet, med suffix borttagna.\n" +" " msgid "no working directory: please specify a revision" -msgstr "" +msgstr "ingen arbetskatalog: specificera en revision" msgid "repository root cannot be destination" -msgstr "" +msgstr "arkivroten kan inte vara destinationen" msgid "cannot archive plain files to stdout" -msgstr "" +msgstr "kan inte arkivera rena filer till stdout" msgid "" "reverse effect of earlier changeset\n" @@ -4960,42 +5035,59 @@ " See 'hg help dates' for a list of formats valid for -d/--date.\n" " " msgstr "" +"omvänd effekten från en tidigare ändring\n" +"\n" +" Arkivera de återkallade ändringarna som en ny ändring. Den nya\n" +" ändringen är ett barn till den återkallade ändringen.\n" +"\n" +" Om du återkallar en annan ändring än toppen, skapas ett nytt huvud.\n" +" Detta huvud kommer att vara en nya toppen och du bör sammanfoga den med\n" +" ett annat huvud.\n" +"\n" +" Flaggan --merge kommer ihåg arbetskatalogens förälder innan\n" +" återkallningen påbörjas, och sammanfogar sedan det nya huvudet med den\n" +" ändringen efteråt. Detta gör att du inte behöver göra sammanfogningen\n" +" manuellt. Resultatet av sammanfogningen arkiveras inte, precis som en\n" +" vanlig sammanfogning.\n" +"\n" +" Se 'hg help dates' för en lista med giltiga format för -d/--date.\n" +" " msgid "please specify just one revision" -msgstr "" +msgstr "specificera bara en revision" msgid "please specify a revision to backout" -msgstr "" +msgstr "specificera en revision att återkalla" msgid "cannot backout change on a different branch" -msgstr "" +msgstr "kan inte återkalla en ändring på en annan gren" msgid "cannot backout a change with no parents" -msgstr "" +msgstr "kan inte återkalla en ändring utan föräldrar" msgid "cannot backout a merge changeset without --parent" -msgstr "" +msgstr "kan inte återkalla en sammanfogande ändring utan --parent" #, python-format msgid "%s is not a parent of %s" -msgstr "" +msgstr "%s är inte en förälder till %s" msgid "cannot use --parent on non-merge changeset" -msgstr "" +msgstr "kan inte använda --parent på icke-sammanfogande ändring" #, python-format msgid "changeset %s backs out changeset %s\n" -msgstr "" +msgstr "ändringen %s återkallar ändringen %s\n" #, python-format msgid "merging with changeset %s\n" -msgstr "" +msgstr "sammanfogar med ändring %s\n" msgid "the backout changeset is a new head - do not forget to merge\n" -msgstr "" +msgstr "återkallningsändringen är ett nytt huvud - glöm inte att sammanfoga\n" msgid "(use \"backout --merge\" if you want to auto-merge)\n" -msgstr "" +msgstr "(använd \"backout --merge\" om du vill auto-sammanfoga)\n" msgid "" "subdivision search of changesets\n" @@ -5146,11 +5238,11 @@ "\n" " Output may be to a file, in which case the name of the file is\n" " given using a format string. The formatting rules are the same as\n" -" for the export command, with the following additions::\n" -"\n" -" %s basename of file being printed\n" -" %d dirname of file being printed, or '.' if in repository root\n" -" %p root-relative path name of file being printed\n" +" for the export command, with the following additions:\n" +"\n" +" :``%s``: basename of file being printed\n" +" :``%d``: dirname of file being printed, or '.' if in repository root\n" +" :``%p``: root-relative path name of file being printed\n" " " msgstr "" @@ -5176,9 +5268,9 @@ " will be the null changeset). Otherwise, clone will initially check\n" " out (in order of precedence):\n" "\n" -" a) the changeset, tag or branch specified with -u/--updaterev\n" -" b) the changeset, tag or branch given with the first -r/--rev\n" -" c) the head of the default branch\n" +" a) the changeset, tag or branch specified with -u/--updaterev\n" +" b) the changeset, tag or branch given with the first -r/--rev\n" +" c) the head of the default branch\n" "\n" " Use 'hg clone -u . src dst' to checkout the source repository's\n" " parent changeset (applicable for local source repositories only).\n" @@ -5187,8 +5279,8 @@ " by listing each changeset (tag, or branch name) with -r/--rev.\n" " If -r/--rev is used, the cloned repository will contain only a subset\n" " of the changesets of the source repository. Only the set of changesets\n" -" defined by all -r/--rev options (including their direct and indirect\n" -" parent changesets) will be pulled into the destination repository.\n" +" defined by all -r/--rev options (including all their ancestors)\n" +" will be pulled into the destination repository.\n" " No subsequent changesets (including subsequent tags) will be present\n" " in the destination.\n" "\n" @@ -5236,9 +5328,9 @@ " förälder kommer att vara null-ändringen). Annars kommer klonen initialt\n" " att hämta ut (i prioritetsordning):\n" "\n" -" a) ändringen, taggen eller grenen specificerad med -u/--updaterev\n" -" b) ändringen, taggen eller grenen given med den första -r/--rev\n" -" c) huvudet på grenen 'default'\n" +" a) ändringen, taggen eller grenen specificerad med -u/--updaterev\n" +" b) ändringen, taggen eller grenen given med den första -r/--rev\n" +" c) huvudet på grenen 'default'\n" "\n" " Använd 'hg clone -u . källa dst' för att hämta ut källkodsarkivets\n" " föräldraänrding (gäller bara för lokala arkiv).\n" @@ -5247,9 +5339,9 @@ " genom att lista varje ändring (märke, eller grennamn) med -r/--rev.\n" " Om -r/--rev används, kommer det klonade arkivet bara att innehålla en\n" " delmängd av ändringarna i källarkivet. Bara ändringarna definierade med\n" -" -r/--rev (inklusive direkta och indirekta föräldrar) kommer att dras in\n" -" i destinationsarkivet. Inga efterföljande ändringar (inklusive\n" -" efterföljande märken) kommer att finnas i destinationen.\n" +" -r/--rev (och alla föräldrar) kommer att dras in i destinationsarkivet.\n" +" Inga efterföljande ändringar (inklusive efterföljande märken) kommer\n" +" att finnas i destinationen.\n" "\n" " Användande av -r/--rev (eller 'clone källa#rev dest') aktiverar också\n" " --pull, även för lokala arkiv.\n" @@ -5574,16 +5666,16 @@ " first parent only.\n" "\n" " Output may be to a file, in which case the name of the file is\n" -" given using a format string. The formatting rules are as follows::\n" -"\n" -" %% literal \"%\" character\n" -" %H changeset hash (40 bytes of hexadecimal)\n" -" %N number of patches being generated\n" -" %R changeset revision number\n" -" %b basename of the exporting repository\n" -" %h short-form changeset hash (12 bytes of hexadecimal)\n" -" %n zero-padded sequence number, starting at 1\n" -" %r zero-padded changeset revision number\n" +" given using a format string. The formatting rules are as follows:\n" +"\n" +" :``%%``: literal \"%\" character\n" +" :``%H``: changeset hash (40 bytes of hexadecimal)\n" +" :``%N``: number of patches being generated\n" +" :``%R``: changeset revision number\n" +" :``%b``: basename of the exporting repository\n" +" :``%h``: short-form changeset hash (12 bytes of hexadecimal)\n" +" :``%n``: zero-padded sequence number, starting at 1\n" +" :``%r``: zero-padded changeset revision number\n" "\n" " Without the -a/--text option, export will avoid generating diffs\n" " of files it detects as binary. With -a, export will generate a\n" @@ -5610,14 +5702,14 @@ " Utmatning kan vara till en fil, och då anges namnet på filen med en\n" " formatsträng. Formateringsreglerna är som följer::\n" "\n" -" %% ett \"%\"-tecken\n" -" %H ändringshash (40 hexadecimala bytes)\n" -" %N antal genererade patchar\n" -" %R ändringens revisionsnummer\n" -" %b basnamn för det exporterande arkivet\n" -" %h kort ändringshash (12 hexadecimala bytes)\n" -" %n nollpaddat sekvensnummer, börjar med 1\n" -" %r nollpaddat ändringsrevisionsnummer\n" +" :``%%``: ett \"%\"-tecken\n" +" :``%H``: ändringshash (40 hexadecimala bytes)\n" +" :``%N``: antal genererade patchar\n" +" :``%R``: ändringens revisionsnummer\n" +" :``%b``: basnamn för det exporterande arkivet\n" +" :``%h``: kort ändringshash (12 hexadecimala bytes)\n" +" :``%n``: nollpaddat sekvensnummer, börjar med 1\n" +" :``%r``: nollpaddat ändringsrevisionsnummer\n" "\n" " Utan flaggan -a/--text, kommer export att undvika skapandet av diffar\n" " av filer som upptäcks vara binära. Med -a, kommer filen att exporteras\n" @@ -5783,25 +5875,24 @@ "alias: %s\n" msgid "(no help text available)" -msgstr "" +msgstr "(ingen hjälptext tillgänglig)" msgid "options:\n" msgstr "flaggor:\n" msgid "no commands defined\n" -msgstr "" - -msgid "enabled extensions:" -msgstr "aktiverade utökningar:" +msgstr "inga kommandon definierade\n" msgid "no help text available" -msgstr "" +msgstr "ingen hjälptext tillgänglig" #, python-format msgid "" "%s extension - %s\n" "\n" msgstr "" +"%s-utökning - %s\n" +"\n" msgid "Mercurial Distributed SCM\n" msgstr "Mercurial Distribuerad SCM\n" @@ -5813,6 +5904,9 @@ "grundläggande kommandon:\n" "\n" +msgid "enabled extensions:" +msgstr "aktiverade utökningar:" + msgid "DEPRECATED" msgstr "FÖRLEGAD" @@ -6417,13 +6511,13 @@ " Transactions are used to encapsulate the effects of all commands\n" " that create new changesets or propagate existing changesets into a\n" " repository. For example, the following commands are transactional,\n" -" and their effects can be rolled back::\n" -"\n" -" commit\n" -" import\n" -" pull\n" -" push (with this repository as destination)\n" -" unbundle\n" +" and their effects can be rolled back:\n" +"\n" +" - commit\n" +" - import\n" +" - pull\n" +" - push (with this repository as destination)\n" +" - unbundle\n" "\n" " This command is not intended for use on public repositories. Once\n" " changes are visible for pull by other users, rolling a transaction\n" @@ -6706,6 +6800,11 @@ " bundle command.\n" " " msgstr "" +"applicera en eller flera filer med ändringar\n" +"\n" +" Applicera en eller flera komprimerade filer med ändringar genererade\n" +" av bundle-kommandot.\n" +" " msgid "" "update working directory\n" @@ -6720,13 +6819,13 @@ " The following rules apply when the working directory contains\n" " uncommitted changes:\n" "\n" -" 1. If neither -c/--check nor -C/--clean is specified, uncommitted\n" -" changes are merged into the requested changeset, and the merged " -"result\n" -" is left uncommitted. Updating and merging will occur only if the\n" -" requested changeset is an ancestor or descendant of the parent\n" -" changeset. Otherwise, the update is aborted and the uncommitted " -"changes\n" +" 1. If neither -c/--check nor -C/--clean is specified, and if\n" +" the requested changeset is an ancestor or descendant of\n" +" the working directory's parent, the uncommitted changes\n" +" are merged into the requested changeset and the merged\n" +" result is left uncommitted. If the requested changeset is\n" +" not an ancestor or descendant (that is, it is on another\n" +" branch), the update is aborted and the uncommitted changes\n" " are preserved.\n" "\n" " 2. With the -c/--check option, the update is aborted and the\n" @@ -6755,12 +6854,13 @@ " Följande regler gäller när arbetskatalogen innehåller oarkiverade\n" " ändringar:\n" "\n" -" 1. Om varken -c/--check eller -C/--clean specificeras, kommer\n" -" oarkiverade ändringar att sammanfogas med den begärda ändringen,\n" -" och det sammanfogade resultatet lämnas oarkiverat. Uppdatering och\n" -" sammanfogning kommer bara att göras om den begärda ändringen är en\n" -" anfader eller ättling till föräldraändringen. Om inte, avbryts\n" -" uppdateringen och de oarkiverade ändringarna lämnas.\n" +" 1. Om varken -c/--check eller -C/--clean specificeras, och om den\n" +" begärda ändringen är en anfader eller ättling till arbetskatalogens\n" +" förälder, kommer oarkiverade ändringar att sammanfogas med den\n" +" begärda ändringen och det sammanfogade resultatet lämnas oarkiverat.\n" +" Om den begärda ändringen inte är en anfader eller ättling (dvs är i\n" +" en annan gren), avbryts uppdateringen och de oarkiverade ändringarna\n" +" bevaras.\n" "\n" " 2. Med flaggan -c/--check avbryts uppdateringen och de oarkiverade\n" " ändringarna lämnas.\n" @@ -6794,13 +6894,21 @@ " integrity of their crosslinks and indices.\n" " " msgstr "" +"verifiera arkivets integritet\n" +"\n" +" Verifiera det aktuella arkivets integritet.\n" +"\n" +" Detta genomför en omfattande kontroll av arkivets integritet, validerar\n" +" hash- och checksummor för varje notering i ändringsloggen, manifestet,\n" +" och spårade filer, såväl som integriteten av korslänkar och indexar.\n" +" " msgid "output version and copyright information" -msgstr "" +msgstr "visa version och copyright-information" #, python-format msgid "Mercurial Distributed SCM (version %s)\n" -msgstr "" +msgstr "Mercurial Distribuerad SCM (version %s)\n" msgid "" "\n" @@ -6808,6 +6916,10 @@ "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" msgstr "" +"\n" +"Copyright (C) 2005-2009 Matt Mackall och andra\n" +"Detta är fri mjukvara; se källkoden för kopieringsvillkor. Det ges INGEN\n" +"garanti; inte ens för SÄLJBARHET eller ATT PASSA FÖR ETT VISST ÄNDAMÅL.\n" msgid "repository root directory or name of overlay bundle file" msgstr "arkivrotkatalog eller namn på påläggsbuntfil" @@ -6918,7 +7030,7 @@ msgstr "visa sammanfattning av ändringar i diffstat-stil" msgid "guess renamed files by similarity (0<=s<=100)" -msgstr "" +msgstr "gissa omdöpta filer efter likhet (0<=s<=100)" msgid "[OPTION]... [FILE]..." msgstr "[FLAGGA]... [FIL]..." @@ -6948,31 +7060,31 @@ msgstr "[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FIL..." msgid "do not pass files through decoders" -msgstr "" +msgstr "passera inte filer genom dekoders" msgid "directory prefix for files in archive" -msgstr "" +msgstr "katalogprefix för filer i arkiv" msgid "revision to distribute" -msgstr "" +msgstr "revision att distribuera" msgid "type of distribution to create" -msgstr "" +msgstr "distributionstyp att skapa" msgid "[OPTION]... DEST" -msgstr "" +msgstr "[FLAGGA]... DEST" msgid "merge with old dirstate parent after backout" -msgstr "" +msgstr "sammanfoga med gamla dirstate-föräldern efter återkallning" msgid "parent to choose when backing out merge" -msgstr "" +msgstr "förälder att välja när en sammanfogning återkallas" msgid "revision to backout" -msgstr "" +msgstr "revision att återkalla" msgid "[OPTION]... [-r] REV" -msgstr "" +msgstr "[FLAGGA]... [-r] REV" msgid "reset bisect state" msgstr "" @@ -7029,7 +7141,7 @@ msgstr "" msgid "[-f] [-a] [-r REV]... [--base REV]... FILE [DEST]" -msgstr "" +msgstr "[-f] [-a] [-r REV]... [--base REV]... FIL [DEST]" msgid "print output to file with formatted name" msgstr "skriv utmatning till fil med formatterat namn" @@ -7049,8 +7161,8 @@ msgid "revision, tag or branch to check out" msgstr "revision, märke eller gren att hämta ut" -msgid "a changeset you would like to have after cloning" -msgstr "en ändring du skulle vilja ha efter kloning" +msgid "clone only the specified revisions and ancestors" +msgstr "klona bara specificerade revisioner och anfäder" msgid "[OPTION]... SOURCE [DEST]" msgstr "[FLAGGA]... KÄLLA [DEST]" @@ -7068,7 +7180,7 @@ msgstr "" msgid "[OPTION]... [SOURCE]... DEST" -msgstr "" +msgstr "[FLAGGA]... [KÄLLA]... DEST" msgid "[INDEX] REV1 REV2" msgstr "" @@ -7449,10 +7561,10 @@ msgstr "" msgid "update to new tip if changesets were unbundled" -msgstr "" +msgstr "uppdatera till ny topp om ändringas packades upp" msgid "[-u] FILE..." -msgstr "" +msgstr "[-u] FIL..." msgid "discard uncommitted changes (no backup)" msgstr "kassera oarkiverade ändringar (ingen backup)" @@ -7516,7 +7628,7 @@ #, python-format msgid "abort: %s\n" -msgstr "" +msgstr "avbryter: %s\n" #, python-format msgid "hg: %s\n" @@ -7616,6 +7728,16 @@ msgstr "" #, python-format +msgid "" +"alias for: hg %s\n" +"\n" +"%s" +msgstr "" +"alias för: hg %s\n" +"\n" +"%s" + +#, python-format msgid "alias '%s' resolves to unknown command '%s'\n" msgstr "" @@ -7624,7 +7746,7 @@ msgstr "" #, python-format -msgid "malformed --config option: %s" +msgid "malformed --config option: %r (use --config section.name=value)" msgstr "" #, python-format @@ -7734,7 +7856,7 @@ msgstr "" msgid "Configuration Files" -msgstr "" +msgstr "Konfigurationsfiler" msgid "Date Formats" msgstr "" @@ -7834,6 +7956,12 @@ msgid "%s hook is invalid (\"%s\" not in a module)" msgstr "" +msgid "exception from first failed import attempt:\n" +msgstr "" + +msgid "exception from second failed import attempt:\n" +msgstr "" + #, python-format msgid "%s hook is invalid (import of \"%s\" failed)" msgstr "" @@ -8579,7 +8707,7 @@ msgstr "" msgid "no username supplied (see \"hg help config\")" -msgstr "" +msgstr "inget användarnamn angivet (se \"hg help config\")" #, python-format msgid "username %s contains a newline\n" diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/ancestor.py --- a/mercurial/ancestor.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/ancestor.py Thu Dec 03 01:06:15 2009 +0100 @@ -9,10 +9,11 @@ def ancestor(a, b, pfunc): """ - return the least common ancestor of nodes a and b or None if there - is no such ancestor. + return a minimal-distance ancestor of nodes a and b, or None if there is no + such ancestor. Note that there can be several ancestors with the same + (minimal) distance, and the one returned is arbitrary. - pfunc must return a list of parent vertices + pfunc must return a list of parent vertices for a given vertex """ if a == b: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/cmdutil.py Thu Dec 03 01:06:15 2009 +0100 @@ -270,31 +270,42 @@ def findrenames(repo, added, removed, threshold): '''find renamed files -- yields (before, after, score) tuples''' + copies = {} ctx = repo['.'] - for a in added: - aa = repo.wread(a) - bestname, bestscore = None, threshold - for r in removed: - if r not in ctx: - continue - rr = ctx.filectx(r).data() + for r in removed: + if r not in ctx: + continue + fctx = ctx.filectx(r) + def score(text): + if not len(text): + return 0.0 + if not fctx.cmp(text): + return 1.0 + if threshold == 1.0: + return 0.0 + orig = fctx.data() # bdiff.blocks() returns blocks of matching lines # count the number of bytes in each equal = 0 - alines = mdiff.splitnewlines(aa) - matches = bdiff.blocks(aa, rr) - for x1,x2,y1,y2 in matches: + alines = mdiff.splitnewlines(text) + matches = bdiff.blocks(text, orig) + for x1, x2, y1, y2 in matches: for line in alines[x1:x2]: equal += len(line) - lengths = len(aa) + len(rr) - if lengths: - myscore = equal*2.0 / lengths - if myscore >= bestscore: - bestname, bestscore = r, myscore - if bestname: - yield bestname, a, bestscore + lengths = len(text) + len(orig) + return equal * 2.0 / lengths + + for a in added: + bestscore = copies.get(a, (None, threshold))[1] + myscore = score(repo.wread(a)) + if myscore >= bestscore: + copies[a] = (r, myscore) + + for dest, v in copies.iteritems(): + source, score = v + yield source, dest, score def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None): if dry_run is None: @@ -744,7 +755,8 @@ cache={ 'parent': '{rev}:{node|formatnode} ', 'manifest': '{rev}:{node|formatnode}', - 'filecopy': '{name} ({source})'}) + 'filecopy': '{name} ({source})', + 'extra': '{key}={value|stringescape}'}) # Cache mapping from rev to a tuple with tag date, tag # distance and tag name self._latesttagcache = {-1: (0, 0, 'null')} diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/commands.py --- a/mercurial/commands.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/commands.py Thu Dec 03 01:06:15 2009 +0100 @@ -1476,7 +1476,7 @@ ui.write('\n') try: - aliases, i = cmdutil.findcmd(name, table, False) + aliases, entry = cmdutil.findcmd(name, table, False) except error.AmbiguousCommand, inst: # py3k fix: except vars can't be used outside the scope of the # except block, nor can be used inside a lambda. python issue4617 @@ -1486,11 +1486,11 @@ return # synopsis - if len(i) > 2: - if i[2].startswith('hg'): - ui.write("%s\n" % i[2]) + if len(entry) > 2: + if entry[2].startswith('hg'): + ui.write("%s\n" % entry[2]) else: - ui.write('hg %s %s\n' % (aliases[0], i[2])) + ui.write('hg %s %s\n' % (aliases[0], entry[2])) else: ui.write('hg %s\n' % aliases[0]) @@ -1499,7 +1499,7 @@ ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:])) # description - doc = gettext(i[0].__doc__) + doc = gettext(entry[0].__doc__) if not doc: doc = _("(no help text available)") if ui.quiet: @@ -1508,8 +1508,8 @@ if not ui.quiet: # options - if i[1]: - option_lists.append((_("options:\n"), i[1])) + if entry[1]: + option_lists.append((_("options:\n"), entry[1])) addglobalopts(False) @@ -2017,7 +2017,6 @@ else: endrev = len(repo) rcache = {} - ncache = {} def getrenamed(fn, rev): '''looks up all renames for a file (up to endrev) the first time the file is given. It indexes on the changerev and only @@ -2025,15 +2024,11 @@ Returns rename info for fn at changerev rev.''' if fn not in rcache: rcache[fn] = {} - ncache[fn] = {} fl = repo.file(fn) for i in fl: - node = fl.node(i) lr = fl.linkrev(i) - renamed = fl.renamed(node) + renamed = fl.renamed(fl.node(i)) rcache[fn][lr] = renamed - if renamed: - ncache[fn][node] = renamed if lr >= endrev: break if rev in rcache[fn]: @@ -2041,12 +2036,10 @@ # If linkrev != rev (i.e. rev not found in rcache) fallback to # filectx logic. - try: return repo[rev][fn].renamed() except error.LookupError: - pass - return None + return None df = False if opts["date"]: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/context.py --- a/mercurial/context.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/context.py Thu Dec 03 01:06:15 2009 +0100 @@ -433,19 +433,17 @@ # sort by revision (per file) which is a topological order visit = [] for f in files: - fn = [(n.rev(), n) for n in needed if n._path == f] - visit.extend(fn) + visit.extend(n for n in needed if n._path == f) hist = {} - for r, f in sorted(visit): + for f in sorted(visit, key=lambda x: x.rev()): curr = decorate(f.data(), f) for p in parents(f): - if p != nullid: - curr = pair(hist[p], curr) - # trim the history of unneeded revs - needed[p] -= 1 - if not needed[p]: - del hist[p] + curr = pair(hist[p], curr) + # trim the history of unneeded revs + needed[p] -= 1 + if not needed[p]: + del hist[p] hist[f] = curr return zip(hist[f][0], hist[f][1].splitlines(True)) diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/dispatch.py --- a/mercurial/dispatch.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/dispatch.py Thu Dec 03 01:06:15 2009 +0100 @@ -200,6 +200,12 @@ self.args = aliasargs(self.fn) + args if cmd not in commands.norepo.split(' '): self.norepo = False + if self.help.startswith("hg " + cmd): + # drop prefix in old-style help lines so hg shows the alias + self.help = self.help[4 + len(cmd):] + self.__doc__ = _("alias for: hg %s\n\n%s") \ + % (definition, self.fn.__doc__) + except error.UnknownCommand: def fn(ui, *args): ui.warn(_("alias '%s' resolves to unknown command '%s'\n") \ @@ -240,14 +246,14 @@ if args: cmd, args = args[0], args[1:] - aliases, i = cmdutil.findcmd(cmd, commands.table, + aliases, entry = cmdutil.findcmd(cmd, commands.table, ui.config("ui", "strict")) cmd = aliases[0] - args = aliasargs(i[0]) + args + args = aliasargs(entry[0]) + args defaults = ui.config("defaults", cmd) if defaults: args = map(util.expandpath, shlex.split(defaults)) + args - c = list(i[1]) + c = list(entry[1]) else: cmd = None c = [] @@ -267,7 +273,7 @@ options[n] = cmdoptions[n] del cmdoptions[n] - return (cmd, cmd and i[0] or None, args, options, cmdoptions) + return (cmd, cmd and entry[0] or None, args, options, cmdoptions) def _parseconfig(ui, config): """parse the --config options from the command line""" diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/hgweb/common.py Thu Dec 03 01:06:15 2009 +0100 @@ -16,6 +16,58 @@ HTTP_METHOD_NOT_ALLOWED = 405 HTTP_SERVER_ERROR = 500 +# Hooks for hgweb permission checks; extensions can add hooks here. Each hook +# is invoked like this: hook(hgweb, request, operation), where operation is +# either read, pull or push. Hooks should either raise an ErrorResponse +# exception, or just return. +# It is possible to do both authentication and authorization through this. +permhooks = [] + +def checkauthz(hgweb, req, op): + '''Check permission for operation based on request data (including + authentication info). Return if op allowed, else raise an ErrorResponse + exception.''' + + user = req.env.get('REMOTE_USER') + + deny_read = hgweb.configlist('web', 'deny_read') + if deny_read and (not user or deny_read == ['*'] or user in deny_read): + raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') + + allow_read = hgweb.configlist('web', 'allow_read') + result = (not allow_read) or (allow_read == ['*']) + if not (result or user in allow_read): + raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') + + if op == 'pull' and not hgweb.allowpull: + raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') + elif op == 'pull' or op is None: # op is None for interface requests + return + + # enforce that you can only push using POST requests + if req.env['REQUEST_METHOD'] != 'POST': + msg = 'push requires POST request' + raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) + + # require ssl by default for pushing, auth info cannot be sniffed + # and replayed + scheme = req.env.get('wsgi.url_scheme') + if hgweb.configbool('web', 'push_ssl', True) and scheme != 'https': + raise ErrorResponse(HTTP_OK, 'ssl required') + + deny = hgweb.configlist('web', 'deny_push') + if deny and (not user or deny == ['*'] or user in deny): + raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + + allow = hgweb.configlist('web', 'allow_push') + result = allow and (allow == ['*'] or user in allow) + if not result: + raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + +# Add the default permhook, which provides simple authorization. +permhooks.append(checkauthz) + + class ErrorResponse(Exception): def __init__(self, code, message=None, headers=[]): Exception.__init__(self) diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/hgweb/hgweb_mod.py Thu Dec 03 01:06:15 2009 +0100 @@ -8,7 +8,7 @@ import os from mercurial import ui, hg, hook, error, encoding, templater -from common import get_mtime, ErrorResponse +from common import get_mtime, ErrorResponse, permhooks from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED from request import wsgirequest @@ -54,7 +54,9 @@ return self.repo.ui.configlist(section, name, default, untrusted=untrusted) - def refresh(self): + def refresh(self, request=None): + if request: + self.repo.ui.environ = request.env mtime = get_mtime(self.repo.root) if mtime != self.mtime: self.mtime = mtime @@ -80,7 +82,7 @@ def run_wsgi(self, req): - self.refresh() + self.refresh(req) # work with CGI variables to create coherent structure # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME @@ -281,42 +283,5 @@ } def check_perm(self, req, op): - '''Check permission for operation based on request data (including - authentication info). Return if op allowed, else raise an ErrorResponse - exception.''' - - user = req.env.get('REMOTE_USER') - - deny_read = self.configlist('web', 'deny_read') - if deny_read and (not user or deny_read == ['*'] or user in deny_read): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') - - allow_read = self.configlist('web', 'allow_read') - result = (not allow_read) or (allow_read == ['*']) - if not (result or user in allow_read): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') - - if op == 'pull' and not self.allowpull: - raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') - elif op == 'pull' or op is None: # op is None for interface requests - return - - # enforce that you can only push using POST requests - if req.env['REQUEST_METHOD'] != 'POST': - msg = 'push requires POST request' - raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) - - # require ssl by default for pushing, auth info cannot be sniffed - # and replayed - scheme = req.env.get('wsgi.url_scheme') - if self.configbool('web', 'push_ssl', True) and scheme != 'https': - raise ErrorResponse(HTTP_OK, 'ssl required') - - deny = self.configlist('web', 'deny_push') - if deny and (not user or deny == ['*'] or user in deny): - raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') - - allow = self.configlist('web', 'allow_push') - result = allow and (allow == ['*'] or user in allow) - if not result: - raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') + for hook in permhooks: + hook(self, req, op) diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/httprepo.py --- a/mercurial/httprepo.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/httprepo.py Thu Dec 03 01:06:15 2009 +0100 @@ -93,7 +93,7 @@ resp_url = resp.geturl() if resp_url.endswith(qs): resp_url = resp_url[:-len(qs)] - if self._url != resp_url: + if self._url.rstrip('/') != resp_url.rstrip('/'): self.ui.status(_('real URL is %s\n') % resp_url) self._url = resp_url try: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/localrepo.py --- a/mercurial/localrepo.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/localrepo.py Thu Dec 03 01:06:15 2009 +0100 @@ -128,6 +128,12 @@ return context.workingctx(self) return context.changectx(self, changeid) + def __contains__(self, changeid): + try: + return bool(self.lookup(changeid)) + except error.RepoLookupError: + return False + def __nonzero__(self): return True @@ -819,6 +825,7 @@ extra, changes) if editor: cctx._text = editor(self, cctx, subs) + edited = (text != cctx._text) # commit subs if subs: @@ -829,7 +836,21 @@ state[s] = (state[s][0], sr) subrepo.writestate(self, state) - ret = self.commitctx(cctx, True) + # Save commit message in case this transaction gets rolled back + # (e.g. by a pretxncommit hook). Leave the content alone on + # the assumption that the user will use the same editor again. + msgfile = self.opener('last-message.txt', 'wb') + msgfile.write(cctx._text) + msgfile.close() + + try: + ret = self.commitctx(cctx, True) + except: + if edited: + msgfn = self.pathto(msgfile.name[len(self.root)+1:]) + self.ui.write( + _('note: commit message saved in %s\n') % msgfn) + raise # update dirstate and mergestate for f in changes[0] + changes[1]: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/mail.py --- a/mercurial/mail.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/mail.py Thu Dec 03 01:06:15 2009 +0100 @@ -160,11 +160,7 @@ return str(email.Header.Header(s, cs)) return s -def addressencode(ui, address, charsets=None, display=False): - '''Turns address into RFC-2047 compliant header.''' - if display or not address: - return address or '' - name, addr = email.Utils.parseaddr(address) +def _addressencode(ui, name, addr, charsets=None): name = headencode(ui, name, charsets) try: acc, dom = addr.split('@') @@ -181,6 +177,26 @@ raise util.Abort(_('invalid local address: %s') % addr) return email.Utils.formataddr((name, addr)) +def addressencode(ui, address, charsets=None, display=False): + '''Turns address into RFC-2047 compliant header.''' + if display or not address: + return address or '' + name, addr = email.Utils.parseaddr(address) + return _addressencode(ui, name, addr, charsets) + +def addrlistencode(ui, addrs, charsets=None, display=False): + '''Turns a list of addresses into a list of RFC-2047 compliant headers. + A single element of input list may contain multiple addresses, but output + always has one address per item''' + if display: + return [a.strip() for a in addrs if a.strip()] + + result = [] + for name, addr in email.Utils.getaddresses(addrs): + if name or addr: + result.append(_addressencode(ui, name, addr, charsets)) + return result + def mimeencode(ui, s, charsets=None, display=False): '''creates mime text object, encodes it if needed, and sets charset and transfer-encoding accordingly.''' diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/revlog.py --- a/mercurial/revlog.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/revlog.py Thu Dec 03 01:06:15 2009 +0100 @@ -1118,10 +1118,19 @@ def ancestor(self, a, b): """calculate the least common ancestor of nodes a and b""" + # fast path, check if it is a descendant + a, b = self.rev(a), self.rev(b) + start, end = sorted((a, b)) + for i in self.descendants(start): + if i == end: + return self.node(start) + elif i > end: + break + def parents(rev): return [p for p in self.parentrevs(rev) if p != nullrev] - c = ancestor.ancestor(self.rev(a), self.rev(b), parents) + c = ancestor.ancestor(a, b, parents) if c is None: return nullid diff -r 60cefb8b3c85 -r e97dd3a8e8d7 mercurial/ui.py --- a/mercurial/ui.py Wed Dec 02 14:30:39 2009 +0200 +++ b/mercurial/ui.py Thu Dec 03 01:06:15 2009 +0100 @@ -29,8 +29,11 @@ self._ocfg = src._ocfg.copy() self._trustusers = src._trustusers.copy() self._trustgroups = src._trustgroups.copy() + self.environ = src.environ self.fixconfig() else: + # shared read-only environment + self.environ = os.environ # we always trust global config files for f in util.rcpath(): self.readconfig(f, trust=True) diff -r 60cefb8b3c85 -r e97dd3a8e8d7 templates/gitweb/fileannotate.tmpl --- a/templates/gitweb/fileannotate.tmpl Wed Dec 02 14:30:39 2009 +0200 +++ b/templates/gitweb/fileannotate.tmpl Thu Dec 03 01:06:15 2009 +0100 @@ -21,6 +21,7 @@ files | changeset | file | +latest | revisions | annotate | diff | diff -r 60cefb8b3c85 -r e97dd3a8e8d7 templates/gitweb/filediff.tmpl --- a/templates/gitweb/filediff.tmpl Wed Dec 02 14:30:39 2009 +0200 +++ b/templates/gitweb/filediff.tmpl Thu Dec 03 01:06:15 2009 +0100 @@ -21,6 +21,7 @@ files | changeset | file | +latest | revisions | annotate | diff | diff -r 60cefb8b3c85 -r e97dd3a8e8d7 templates/gitweb/filerevision.tmpl --- a/templates/gitweb/filerevision.tmpl Wed Dec 02 14:30:39 2009 +0200 +++ b/templates/gitweb/filerevision.tmpl Thu Dec 03 01:06:15 2009 +0100 @@ -21,6 +21,7 @@ files | changeset | file | +latest | revisions | annotate | diff | diff -r 60cefb8b3c85 -r e97dd3a8e8d7 templates/map-cmdline.changelog --- a/templates/map-cmdline.changelog Wed Dec 02 14:30:39 2009 +0200 +++ b/templates/map-cmdline.changelog Thu Dec 03 01:06:15 2009 +0100 @@ -1,11 +1,14 @@ header = '{date|shortdate} {author|person} <{author|email}>\n\n' header_verbose = '' -changeset = '\t* {files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\t[{node|short}]{tags}\n\n' +changeset = '\t* {files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\t[{node|short}]{tags}{branches}\n\n' changeset_quiet = '\t* {desc|firstline|fill68|tabindent|strip}\n\n' -changeset_verbose = '{date|isodate} {author|person} <{author|email}> ({node|short}{tags})\n\n\t* {file_adds|stringify|fill68|tabindent}{file_dels|stringify|fill68|tabindent}{files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\n' +changeset_verbose = '{date|isodate} {author|person} <{author|email}> ({node|short}{tags}{branches})\n\n\t* {file_adds|stringify|fill68|tabindent}{file_dels|stringify|fill68|tabindent}{files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\n' start_tags = ' [' tag = '{tag}, ' last_tag = '{tag}]' +start_branches = ' <' +branch = '{branch}, ' +last_branch = '{branch}>' file = '{file}, ' last_file = '{file}:\n\t' file_add = '{file_add}, ' diff -r 60cefb8b3c85 -r e97dd3a8e8d7 templates/raw/map --- a/templates/raw/map Wed Dec 02 14:30:39 2009 +0200 +++ b/templates/raw/map Thu Dec 03 01:06:15 2009 +0100 @@ -21,3 +21,7 @@ notfound = notfound.tmpl error = error.tmpl indexentry = '{url}\n' +tags = '{entries%tagentry}' +tagentry = '{tag} {node}\n' +branches = '{entries%branchentry}' +branchentry = '{branch} {node} {status}\n' diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/blacklist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blacklist Thu Dec 03 01:06:15 2009 +0100 @@ -0,0 +1,37 @@ +# ConfigParser format +# Definitions of blacklists for run-tests.py +# +# Identify in config sections a list of tests you want to be skipped. +# Section names are meant to be used as targets for run-tests.py --blacklist +# option. +# "test-" prefixes should be omitted from test names. Values are not used. +# +# e.g. if your file looks like: +## [example] +## hgrc = +## help = "this string is not used" +# then calling "run-tests.py --blacklist example" will exclude test-hgrc and +# test-help from the list of tests to run. + +[inotify-failures] +# When --inotify is activated, help output and config changes: +debugcomplete = +empty = +fncache = +globalopts = +help = +hgrc = +inherit-mode = +qrecord = +strict = + +# --inotify activates de facto the inotify extension. It does not play well +# with inotify-specific tests, which activate/desactivate inotify at will: +inotify = +inotify-debuginotify = +inotify-dirty-dirstate = +inotify-issue1208 = +inotify-issue1371 = +inotify-issue1542 = +inotify-issue1556 = +inotify-lookup = diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/run-tests.py --- a/tests/run-tests.py Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/run-tests.py Thu Dec 03 01:06:15 2009 +0100 @@ -41,6 +41,7 @@ # completes fairly quickly, includes both shell and Python scripts, and # includes some scripts that run daemon processes.) +from ConfigParser import ConfigParser import difflib import errno import optparse @@ -130,6 +131,11 @@ help="use pure Python code instead of C extensions") parser.add_option("-3", "--py3k-warnings", action="store_true", help="enable Py3k warnings on Python 2.6+") + parser.add_option("--inotify", action="store_true", + help="enable inotify extension when running tests") + parser.add_option("--blacklist", action="append", + help="skip tests listed in the specified section of " + "the blacklist file") for option, default in defaults.items(): defaults[option] = int(os.environ.get(*default)) @@ -195,6 +201,14 @@ if options.py3k_warnings: if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0): parser.error('--py3k-warnings can only be used on Python 2.6+') + if options.blacklist: + configparser = ConfigParser() + configparser.read("blacklist") + blacklist = dict() + for section in options.blacklist: + for (item, value) in configparser.items(section): + blacklist["test-" + item] = section + options.blacklist = blacklist return (options, args) @@ -293,10 +307,18 @@ script = os.path.realpath(sys.argv[0]) hgroot = os.path.dirname(os.path.dirname(script)) os.chdir(hgroot) + nohome = '--home=""' + if os.name == 'nt': + # The --home="" trick works only on OS where os.sep == '/' + # because of a distutils convert_path() fast-path. Avoid it at + # least on Windows for now, deal with .pydistutils.cfg bugs + # when they happen. + nohome = '' cmd = ('%s setup.py %s clean --all' ' install --force --prefix="%s" --install-lib="%s"' - ' --install-scripts="%s" >%s 2>&1' - % (sys.executable, pure, INST, PYTHONDIR, BINDIR, installerrs)) + ' --install-scripts="%s" %s >%s 2>&1' + % (sys.executable, pure, INST, PYTHONDIR, BINDIR, nohome, + installerrs)) vlog("# Running", cmd) if os.system(cmd) == 0: if not options.verbose: @@ -449,6 +471,11 @@ hgrc.write('backout = -d "0 0"\n') hgrc.write('commit = -d "0 0"\n') hgrc.write('tag = -d "0 0"\n') + if options.inotify: + hgrc.write('[extensions]\n') + hgrc.write('inotify=\n') + hgrc.write('[inotify]\n') + hgrc.write('pidfile=%s\n' % DAEMON_PIDS) hgrc.close() err = os.path.join(TESTDIR, test+".err") @@ -715,6 +742,13 @@ fails = [] for test in tests: + if options.blacklist: + section = options.blacklist.get(test) + if section is not None: + skips.append((test, "blacklisted (%s section)" % section)) + skipped += 1 + continue + if options.retest and not os.path.exists(test + ".err"): skipped += 1 continue diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-command-template --- a/tests/test-command-template Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-command-template Thu Dec 03 01:06:15 2009 +0100 @@ -93,7 +93,7 @@ echo "# keys work" for key in author branches date desc file_adds file_dels file_mods \ - files manifest node parents rev tags diffstat; do + files manifest node parents rev tags diffstat extras; do for mode in '' --verbose --debug; do hg log $mode --template "$key$mode: {$key}\n" done diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-command-template.out --- a/tests/test-command-template.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-command-template.out Thu Dec 03 01:06:15 2009 +0100 @@ -150,7 +150,7 @@ 1970-01-17 person * new branch - [32a18f097fcc] + [32a18f097fcc] 1970-01-16 person @@ -569,6 +569,33 @@ diffstat--debug: 1: +4/-0 diffstat--debug: 1: +2/-0 diffstat--debug: 1: +1/-0 +extras: branch=default +extras: branch=default +extras: branch=default +extras: branch=default +extras: branch=foo +extras: branch=default +extras: branch=default +extras: branch=default +extras: branch=default +extras--verbose: branch=default +extras--verbose: branch=default +extras--verbose: branch=default +extras--verbose: branch=default +extras--verbose: branch=foo +extras--verbose: branch=default +extras--verbose: branch=default +extras--verbose: branch=default +extras--verbose: branch=default +extras--debug: branch=default +extras--debug: branch=default +extras--debug: branch=default +extras--debug: branch=default +extras--debug: branch=foo +extras--debug: branch=default +extras--debug: branch=default +extras--debug: branch=default +extras--debug: branch=default # filters work hostname diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-convert --- a/tests/test-convert Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-convert Thu Dec 03 01:06:15 2009 +0100 @@ -50,3 +50,10 @@ # override $PATH to ensure p4 not visible; use $PYTHON in case we're # running from a devel copy, not a temp installation PATH=$BINDIR $PYTHON $BINDIR/hg convert emptydir 2>&1 | sed 's,file://.*/emptydir,.../emptydir,g' + +echo % convert with imaginary source type +hg convert --source-type foo a a-foo +echo % convert with imaginary sink type +hg convert --dest-type foo a a-foo + +true diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-convert-filemap --- a/tests/test-convert-filemap Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-convert-filemap Thu Dec 03 01:06:15 2009 +0100 @@ -16,9 +16,11 @@ echo foo > foo echo baz > baz -mkdir dir +mkdir -p dir/subdir echo dir/file >> dir/file echo dir/file2 >> dir/file2 +echo dir/subdir/file3 >> dir/subdir/file3 +echo dir/subdir/file4 >> dir/subdir/file4 hg ci -d '0 0' -qAm '0: add foo baz dir/' echo bar > bar @@ -114,6 +116,8 @@ include copied rename foo foo2 rename copied copied2 +exclude dir/subdir +include dir/subdir/file3 EOF hg -q convert --filemap renames.fmap --datesort source renames.repo hg up -q -R renames.repo diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-convert-filemap.out --- a/tests/test-convert-filemap.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-convert-filemap.out Thu Dec 03 01:06:15 2009 +0100 @@ -16,7 +16,7 @@ |/ o 1 "1: add bar quux; copy foo to copied" files: bar copied quux | -o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 foo +o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/subdir/file3 dir/subdir/file4 foo % final file versions in this repo: 9463f52fe115e377cf2878d4fc548117211063f2 644 bar @@ -24,6 +24,8 @@ 6ca237634e1f6bee1b6db94292fb44f092a25842 644 copied 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file 75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2 +5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3 +57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd @@ -144,10 +146,11 @@ | o 1 "1: add bar quux; copy foo to copied" files: copied2 | -o 0 "0: add foo baz dir/" files: dir2/file foo2 +o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2 e5e3d520be9be45937d0b06b004fadcd6c221fa2 644 copied2 3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file +5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3 9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2 copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd copied: diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-convert.out --- a/tests/test-convert.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-convert.out Thu Dec 03 01:06:15 2009 +0100 @@ -259,3 +259,8 @@ emptydir does not look like a Bazaar repo cannot find required "p4" tool abort: emptydir: missing or unsupported repository +% convert with imaginary source type +initializing destination a-foo repository +abort: foo: invalid source repository type +% convert with imaginary sink type +abort: foo: invalid destination repository type diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-fncache.out --- a/tests/test-fncache.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-fncache.out Thu Dec 03 01:06:15 2009 +0100 @@ -50,6 +50,7 @@ .hg/data/tst.d.hg .hg/data/tst.d.hg/foo.i .hg/dirstate +.hg/last-message.txt .hg/requires .hg/undo .hg/undo.branch @@ -59,6 +60,7 @@ .hg .hg/00changelog.i .hg/dirstate +.hg/last-message.txt .hg/requires .hg/store .hg/store/00changelog.i diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-hgweb-commands --- a/tests/test-hgweb-commands Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-hgweb-commands Thu Dec 03 01:06:15 2009 +0100 @@ -35,8 +35,8 @@ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw' echo % Overviews -"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/tags/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" -"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/branches/?style=gitweb' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//" +"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags' +"$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches' "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb' "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb' diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-hgweb-commands.out --- a/tests/test-hgweb-commands.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-hgweb-commands.out Thu Dec 03 01:06:15 2009 +0100 @@ -465,97 +465,12 @@ % Overviews 200 Script output follows - - - http://127.0.0.1/ - - - test: tags - test tag history - Mercurial SCM - 1970-01-01T00:00:00+00:00 - - - 1.0 - - http://127.0.0.1/#tag-2ef0ac749a14e4f57a5a822464a0902c6f7f448f - 1970-01-01T00:00:00+00:00 - 1970-01-01T00:00:00+00:00 - 1.0 - - - +tip 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe +1.0 2ef0ac749a14e4f57a5a822464a0902c6f7f448f 200 Script output follows - - - - - - - - - -test: Branches - - - - - - - - - -
 
- - - - - - - - - - - - - - -
1970-01-011d22e65f027estable
1970-01-01a4f92ed23982default
- - - - - +stable 1d22e65f027e5a0609357e7d8e7508cd2ba5d2fe open +default a4f92ed23982be056b9852de5dfe873eaac7f0de inactive 200 Script output follows diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-inherit-mode.out --- a/tests/test-inherit-mode.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-inherit-mode.out Thu Dec 03 01:06:15 2009 +0100 @@ -14,6 +14,7 @@ 00700 ./.hg/ 00600 ./.hg/00changelog.i 00660 ./.hg/dirstate +00660 ./.hg/last-message.txt 00600 ./.hg/requires 00770 ./.hg/store/ 00660 ./.hg/store/00changelog.i diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-non-interactive-wsgi --- a/tests/test-non-interactive-wsgi Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-non-interactive-wsgi Thu Dec 03 01:06:15 2009 +0100 @@ -60,9 +60,14 @@ 'SERVER_PROTOCOL': 'HTTP/1.0' } -hgweb('.')(env, startrsp) +i = hgweb('.') +i(env, startrsp) print '---- ERRORS' print errors.getvalue() +print '---- OS.ENVIRON wsgi variables' +print sorted([x for x in os.environ if x.startswith('wsgi')]) +print '---- request.ENVIRON wsgi variables' +print sorted([x for x in i.repo.ui.environ if x.startswith('wsgi')]) EOF python request.py diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-non-interactive-wsgi.out --- a/tests/test-non-interactive-wsgi.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-non-interactive-wsgi.out Thu Dec 03 01:06:15 2009 +0100 @@ -10,3 +10,7 @@ [('Content-Type', 'text/html; charset=ascii')] ---- ERRORS +---- OS.ENVIRON wsgi variables +[] +---- request.ENVIRON wsgi variables +['wsgi.errors', 'wsgi.input', 'wsgi.multiprocess', 'wsgi.multithread', 'wsgi.run_once', 'wsgi.url_scheme', 'wsgi.version'] diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-patchbomb --- a/tests/test-patchbomb Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-patchbomb Thu Dec 03 01:06:15 2009 +0100 @@ -169,6 +169,12 @@ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \ -c bar -s test -r 0:1 | fixheaders +echo "% test multi-address parsing" +hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t 'spam' \ + -t toast -c 'foo,bar@example.com' -c '"A, B <>" ' -s test -r 0 \ + --config email.bcc='"Quux, A." ' +cat tmp.mbox | fixheaders + echo "% test multi-byte domain parsing" UUML=`printf '\374'` HGENCODING=iso-8859-1 diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-patchbomb.out --- a/tests/test-patchbomb.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-patchbomb.out Thu Dec 03 01:06:15 2009 +0100 @@ -1469,6 +1469,39 @@ @@ -0,0 +1,1 @@ +b +% test multi-address parsing +This patch series consists of 1 patches. + + +Writing [PATCH] test ... +From quux Tue Jan 01 00:01:01 1980 +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [PATCH] test +X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab +Message-Id: <8580ff50825a50c8f716.315532860@ +User-Agent: Mercurial-patchbomb +Date: Tue, 01 Jan 1980 00:01:00 +0000 +From: quux +To: spam , eggs, toast +Cc: foo, bar@example.com, "A, B <>" +Bcc: "Quux, A." + +# HG changeset patch +# User test +# Date 1 0 +# Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab +# Parent 0000000000000000000000000000000000000000 +a + +diff -r 000000000000 -r 8580ff50825a a +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/a Thu Jan 01 00:00:01 1970 +0000 +@@ -0,0 +1,1 @@ ++a + + % test multi-byte domain parsing This patch series consists of 1 patches. diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-rollback --- a/tests/test-rollback Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-rollback Thu Dec 03 01:06:15 2009 +0100 @@ -15,14 +15,34 @@ hg status echo % Test issue 902 -hg commit -m "test" +hg commit -m "test2" hg branch test hg rollback hg branch +echo '% Test issue 1635 (commit message saved)' +echo '.hg/last-message.txt:' +cat .hg/last-message.txt ; echo + echo % Test rollback of hg before issue 902 was fixed -hg commit -m "test" +hg commit -m "test3" hg branch test rm .hg/undo.branch hg rollback hg branch + +echo '% rollback by pretxncommit saves commit message (issue 1635)' +echo a >> a +hg --config hooks.pretxncommit=false commit -m"precious commit message" +echo '.hg/last-message.txt:' +cat .hg/last-message.txt ; echo + +echo '% same thing, but run $EDITOR' +cat > $HGTMP/editor <<'__EOF__' +#!/bin/sh +echo "another precious commit message" > "$1" +__EOF__ +chmod +x $HGTMP/editor +HGEDITOR=$HGTMP/editor hg --config hooks.pretxncommit=false commit +echo '.hg/last-message.txt:' +cat .hg/last-message.txt diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-rollback.out --- a/tests/test-rollback.out Wed Dec 02 14:30:39 2009 +0200 +++ b/tests/test-rollback.out Thu Dec 03 01:06:15 2009 +0100 @@ -20,8 +20,24 @@ marked working directory as branch test rolling back last transaction default +% Test issue 1635 (commit message saved) +.hg/last-message.txt: +test2 % Test rollback of hg before issue 902 was fixed marked working directory as branch test rolling back last transaction Named branch could not be reset, current branch still is: test test +% rollback by pretxncommit saves commit message (issue 1635) +transaction abort! +rollback completed +abort: pretxncommit hook exited with status 1 +.hg/last-message.txt: +precious commit message +% same thing, but run $EDITOR +transaction abort! +rollback completed +note: commit message saved in .hg/last-message.txt +abort: pretxncommit hook exited with status 1 +.hg/last-message.txt: +another precious commit message diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-share --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-share Thu Dec 03 01:06:15 2009 +0100 @@ -0,0 +1,42 @@ +#!/bin/sh + +echo "[extensions]" >> $HGRCPATH +echo "share = " >> $HGRCPATH + +echo % prepare repo1 +hg init repo1 +cd repo1 +echo a > a +hg commit -A -m'init' + +echo % share it +cd .. +hg share repo1 repo2 + +echo % contents of repo2/.hg +cd repo2 +[ -d .hg/store ] \ + && echo "fail: .hg/store should not exist" \ + || echo "pass: .hg/store does not exist" +cat .hg/sharedpath | sed "s:$HGTMP:*HGTMP*:"; echo + +echo % commit in shared clone +echo a >> a +hg commit -m'change in shared clone' + +echo % check original +cd ../repo1 +hg log +hg update +cat a # should be two lines of "a" + +echo % commit in original +echo b > b +hg commit -A -m'another file' + +echo % check in shared clone +cd ../repo2 +hg log +hg update +cat b # should exist with one "b" + diff -r 60cefb8b3c85 -r e97dd3a8e8d7 tests/test-share.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-share.out Thu Dec 03 01:06:15 2009 +0100 @@ -0,0 +1,45 @@ +% prepare repo1 +adding a +% share it +updating working directory +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +% contents of repo2/.hg +pass: .hg/store does not exist +*HGTMP*/test-share/repo1/.hg +% commit in shared clone +% check original +changeset: 1:8af4dc49db9e +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: change in shared clone + +changeset: 0:d3873e73d99e +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: init + +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +a +a +% commit in original +adding b +% check in shared clone +changeset: 2:c2e0ac586386 +tag: tip +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: another file + +changeset: 1:8af4dc49db9e +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: change in shared clone + +changeset: 0:d3873e73d99e +user: test +date: Thu Jan 01 00:00:00 1970 +0000 +summary: init + +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +b