Mercurial > hg
changeset 11161:a2c32edc407b
Merge with i18n
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 11 May 2010 17:12:10 -0500 |
parents | b203a95fe68b (diff) 8c8a713f6dac (current diff) |
children | d6f378562397 |
files | |
diffstat | 52 files changed, 910 insertions(+), 225 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/mergetools.hgrc Sun May 09 00:15:13 2010 +0200 +++ b/contrib/mergetools.hgrc Tue May 11 17:12:10 2010 -0500 @@ -13,7 +13,7 @@ gvimdiff.priority=-9 merge.checkconflicts=True -merge.priority=-10 +merge.priority=-100 gpyfm.gui=True
--- a/doc/hgrc.5.txt Sun May 09 00:15:13 2010 +0200 +++ b/doc/hgrc.5.txt Tue May 11 17:12:10 2010 -0500 @@ -454,7 +454,8 @@ Default: ``$local $base $other`` ``premerge`` Attempt to run internal non-interactive 3-way merge tool before - launching external tool. + launching external tool. Options are ``true``, ``false``, or ``keep`` + to leave markers in the file if the premerge fails. Default: True ``binary`` This tool can merge binary files. Defaults to False, unless tool @@ -462,13 +463,21 @@ ``symlink`` This tool can merge symlinks. Defaults to False, even if tool was selected by file pattern match. -``checkconflicts`` - Check whether there are conflicts even though the tool reported - success. +``check`` + A list of merge success-checking options: + + ``changed`` + Ask whether merge was successful when the merged file shows no changes. + ``conflicts`` + Check whether there are conflicts even though the tool reported success. + ``prompt`` + Always prompt for merge success, regardless of success reported by tool. + +``checkchanged`` + True is equivalent to ``check = changed``. Default: False -``checkchanged`` - Check whether outputs were written even though the tool reported - success. +``checkconflicts`` + True is equivalent to ``check = conflicts``. Default: False ``fixeol`` Attempt to fix up EOL changes caused by the merge tool.
--- a/hgext/acl.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/acl.py Tue May 11 17:12:10 2010 -0500 @@ -80,9 +80,11 @@ pretxnchangegroup.acl = python:hgext.acl.hook [acl] - # Check whether the source of incoming changes is in this list where - # "serve" == ssh or http, and "push", "pull" and "bundle" are the - # corresponding hg commands. + # Allow or deny access for incoming changes only if their source is + # listed here, let them pass otherwise. Source is "serve" for all + # remote access (http or ssh), "push", "pull" or "bundle" when the + # related commands are run locally. + # Default: serve sources = serve [acl.deny.branches] @@ -126,7 +128,7 @@ src/main/resources/DONT-TOUCH-THIS.txt = * [acl.allow] - # if acl.allow not present, all users allowed by default + # if acl.allow is not present, all users are allowed by default # empty acl.allow = no users allowed # User "doc_writer" has write access to any file under the "docs" @@ -148,7 +150,7 @@ from mercurial.i18n import _ from mercurial import util, match -import getpass, urllib, grp +import getpass, urllib def _getusers(ui, group): @@ -159,7 +161,10 @@ ui.debug('acl: "%s" not defined in [acl.groups]\n' % group) # If no users found in group definition, get users from OS-level group - return grp.getgrnam(group).gr_mem + try: + return util.groupmembers(group) + except KeyError: + raise util.Abort(_("group '%s' is undefined") % group) def _usermatch(ui, user, usersorgroups):
--- a/hgext/convert/bzr.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/bzr.py Tue May 11 17:12:10 2010 -0500 @@ -109,18 +109,16 @@ # the file is not available anymore - was deleted raise IOError(_('%s is not available in %s anymore') % (name, rev)) + mode = self._modecache[(name, rev)] if kind == 'symlink': target = revtree.get_symlink_target(fileid) if target is None: raise util.Abort(_('%s.%s symlink has no target') % (name, rev)) - return target + return target, mode else: sio = revtree.get_file(fileid) - return sio.read() - - def getmode(self, name, rev): - return self._modecache[(name, rev)] + return sio.read(), mode def getchanges(self, version): # set up caches: modecache and revtree
--- a/hgext/convert/common.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/common.py Tue May 11 17:12:10 2010 -0500 @@ -77,15 +77,10 @@ raise NotImplementedError() def getfile(self, name, rev): - """Return file contents as a string. rev is the identifier returned - by a previous call to getchanges(). Raise IOError to indicate that - name was deleted in rev. - """ - raise NotImplementedError() - - def getmode(self, name, rev): - """Return file mode, eg. '', 'x', or 'l'. rev is the identifier - returned by a previous call to getchanges(). + """Return a pair (data, mode) where data is the file content + as a string and mode one of '', 'x' or 'l'. rev is the + identifier returned by a previous call to getchanges(). Raise + IOError to indicate that name was deleted in rev. """ raise NotImplementedError() @@ -192,8 +187,8 @@ changeset. 'files' is a list of (path, version) tuples, 'copies' is a dictionary mapping destinations to sources, 'source' is the source repository, and 'revmap' is a mapfile - of source revisions to converted revisions. Only getfile(), - getmode(), and lookuprev() should be called on 'source'. + of source revisions to converted revisions. Only getfile() and + lookuprev() should be called on 'source'. Note that the sink repository is not told to update itself to a particular revision (or even what that revision would be)
--- a/hgext/convert/convcmd.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/convcmd.py Tue May 11 17:12:10 2010 -0500 @@ -72,6 +72,25 @@ ui.note(_("convert: %s\n") % inst) raise util.Abort(_('%s: unknown repository type') % path) +class progresssource(object): + def __init__(self, ui, source, filecount): + self.ui = ui + self.source = source + self.filecount = filecount + self.retrieved = 0 + + def getfile(self, file, rev): + self.retrieved += 1 + self.ui.progress(_('retrieving file'), self.retrieved, + item=file, total=self.filecount) + return self.source.getfile(file, rev) + + def lookuprev(self, rev): + return self.source.lookuprev(rev) + + def close(self): + self.ui.progress(_('retrieving file'), None) + class converter(object): def __init__(self, ui, source, dest, revmapfile, opts): @@ -111,11 +130,13 @@ if n in known or n in self.map: continue known.add(n) + self.ui.progress(_('scanning'), len(known), unit=_('revisions')) commit = self.cachecommit(n) parents[n] = [] for p in commit.parents: parents[n].append(p) visit.append(p) + self.ui.progress(_('scanning'), None) return parents @@ -302,8 +323,10 @@ parents = [self.map.get(p, p) for p in parents] except KeyError: parents = [b[0] for b in pbranches] + source = progresssource(self.ui, self.source, len(files)) newnode = self.dest.putcommit(files, copies, parents, commit, - self.source, self.map) + source, self.map) + source.close() self.source.converted(rev, newnode) self.map[rev] = newnode @@ -321,7 +344,7 @@ c = None self.ui.status(_("converting...\n")) - for c in t: + for i, c in enumerate(t): num -= 1 desc = self.commitcache[c].desc if "\n" in desc: @@ -331,7 +354,10 @@ # 'utf-8' self.ui.status("%d %s\n" % (num, recode(desc))) self.ui.note(_("source: %s\n") % recode(c)) + self.ui.progress(_('converting'), i, unit=_('revisions'), + total=len(t)) self.copy(c) + self.ui.progress(_('converting'), None) tags = self.source.gettags() ctags = {}
--- a/hgext/convert/cvs.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/cvs.py Tue May 11 17:12:10 2010 -0500 @@ -200,7 +200,7 @@ self._parse() return self.heads - def _getfile(self, name, rev): + def getfile(self, name, rev): def chunkedread(fp, count): # file-objects returned by socked.makefile() do not handle @@ -216,6 +216,7 @@ output.write(data) return output.getvalue() + self._parse() if rev.endswith("(DEAD)"): raise IOError @@ -255,18 +256,8 @@ else: raise util.Abort(_("unknown CVS response: %s") % line) - def getfile(self, file, rev): - self._parse() - data, mode = self._getfile(file, rev) - self.modecache[(file, rev)] = mode - return data - - def getmode(self, file, rev): - return self.modecache[(file, rev)] - def getchanges(self, rev): self._parse() - self.modecache = {} return sorted(self.files[rev].iteritems()), {} def getcommit(self, rev):
--- a/hgext/convert/darcs.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/darcs.py Tue May 11 17:12:10 2010 -0500 @@ -157,11 +157,11 @@ def getfile(self, name, rev): if rev != self.lastrev: raise util.Abort(_('internal calling inconsistency')) - return open(os.path.join(self.tmppath, name), 'rb').read() - - def getmode(self, name, rev): - mode = os.lstat(os.path.join(self.tmppath, name)).st_mode - return (mode & 0111) and 'x' or '' + path = os.path.join(self.tmppath, name) + data = open(path, 'rb').read() + mode = os.lstat(path).st_mode + mode = (mode & 0111) and 'x' or '' + return data, mode def gettags(self): return self.tags
--- a/hgext/convert/filemap.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/filemap.py Tue May 11 17:12:10 2010 -0500 @@ -100,8 +100,7 @@ # # - Filter and rename files. This is mostly wrapped by the filemapper # class above. We hide the original filename in the revision that is -# returned by getchanges to be able to find things later in getfile -# and getmode. +# returned by getchanges to be able to find things later in getfile. # # - Return only revisions that matter for the files we're interested in. # This involves rewriting the parents of the original revision to @@ -318,10 +317,9 @@ self.convertedorder.append((rev, True, None)) self._discard(*parents) - # Get the real changes and do the filtering/mapping. - # To be able to get the files later on in getfile and getmode, - # we hide the original filename in the rev part of the return - # value. + # Get the real changes and do the filtering/mapping. To be + # able to get the files later on in getfile, we hide the + # original filename in the rev part of the return value. changes, copies = self.base.getchanges(rev) newnames = {} files = [] @@ -345,10 +343,6 @@ realname, realrev = rev return self.base.getfile(realname, realrev) - def getmode(self, name, rev): - realname, realrev = rev - return self.base.getmode(realname, realrev) - def gettags(self): return self.base.gettags()
--- a/hgext/convert/git.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/git.py Tue May 11 17:12:10 2010 -0500 @@ -67,10 +67,9 @@ return data def getfile(self, name, rev): - return self.catfile(rev, "blob") - - def getmode(self, name, rev): - return self.modecache[(name, rev)] + data = self.catfile(rev, "blob") + mode = self.modecache[(name, rev)] + return data, mode def getchanges(self, version): self.modecache = {}
--- a/hgext/convert/gnuarch.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/gnuarch.py Tue May 11 17:12:10 2010 -0500 @@ -54,7 +54,6 @@ self.changes = {} self.parents = {} self.tags = {} - self.modecache = {} self.catlogparser = Parser() self.locale = locale.getpreferredencoding() self.archives = [] @@ -142,16 +141,9 @@ if not os.path.exists(os.path.join(self.tmppath, name)): raise IOError - data, mode = self._getfile(name, rev) - self.modecache[(name, rev)] = mode - - return data - - def getmode(self, name, rev): - return self.modecache[(name, rev)] + return self._getfile(name, rev) def getchanges(self, rev): - self.modecache = {} self._update(rev) changes = [] copies = {}
--- a/hgext/convert/hg.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/hg.py Tue May 11 17:12:10 2010 -0500 @@ -134,11 +134,11 @@ files = dict(files) def getfilectx(repo, memctx, f): v = files[f] - data = source.getfile(f, v) - e = source.getmode(f, v) + data, mode = source.getfile(f, v) if f == '.hgtags': data = self._rewritetags(source, revmap, data) - return context.memfilectx(f, data, 'l' in e, 'x' in e, copies.get(f)) + return context.memfilectx(f, data, 'l' in mode, 'x' in mode, + copies.get(f)) pl = [] for p in parents: @@ -266,13 +266,11 @@ def getfile(self, name, rev): try: - return self.changectx(rev)[name].data() + fctx = self.changectx(rev)[name] + return fctx.data(), fctx.flags() except error.LookupError, err: raise IOError(err) - def getmode(self, name, rev): - return self.changectx(rev).manifest().flags(name) - def getchanges(self, rev): ctx = self.changectx(rev) parents = self.parents(ctx)
--- a/hgext/convert/monotone.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/monotone.py Tue May 11 17:12:10 2010 -0500 @@ -192,18 +192,16 @@ return (files.items(), copies) - def getmode(self, name, rev): - self.mtnloadmanifest(rev) - node, attr = self.files.get(name, (None, "")) - return attr - def getfile(self, name, rev): if not self.mtnisfile(name, rev): raise IOError() # file was deleted or renamed try: - return self.mtnrun("get_file_of", name, r=rev) + data = self.mtnrun("get_file_of", name, r=rev) except: raise IOError() # file was deleted or renamed + self.mtnloadmanifest(rev) + node, attr = self.files.get(name, (None, "")) + return data, attr def getcommit(self, rev): certs = self.mtngetcerts(rev)
--- a/hgext/convert/p4.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/p4.py Tue May 11 17:12:10 2010 -0500 @@ -41,7 +41,6 @@ self.parent = {} self.encoding = "latin_1" self.depotname = {} # mapping from local name to depot name - self.modecache = {} self.re_type = re.compile( "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)" "(\+\w+)?$") @@ -183,17 +182,12 @@ if mode is None: raise IOError(0, "bad stat") - self.modecache[(name, rev)] = mode - if keywords: contents = keywords.sub("$\\1$", contents) if mode == "l" and contents.endswith("\n"): contents = contents[:-1] - return contents - - def getmode(self, name, rev): - return self.modecache[(name, rev)] + return contents, mode def getchanges(self, rev): return self.files[rev], {}
--- a/hgext/convert/subversion.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/convert/subversion.py Tue May 11 17:12:10 2010 -0500 @@ -371,22 +371,13 @@ return self.heads - def getfile(self, file, rev): - data, mode = self._getfile(file, rev) - self.modecache[(file, rev)] = mode - return data - - def getmode(self, file, rev): - return self.modecache[(file, rev)] - def getchanges(self, rev): if self._changescache and self._changescache[0] == rev: return self._changescache[1] self._changescache = None - self.modecache = {} (paths, parents) = self.paths[rev] if parents: - files, copies = self.expandpaths(rev, paths, parents) + files, self.removed, copies = self.expandpaths(rev, paths, parents) else: # Perform a full checkout on roots uuid, module, revnum = self.revsplit(rev) @@ -395,6 +386,7 @@ files = [n for n, e in entries.iteritems() if e.kind == svn.core.svn_node_file] copies = {} + self.removed = set() files.sort() files = zip(files, [rev] * len(files)) @@ -610,10 +602,7 @@ return prevmodule def expandpaths(self, rev, paths, parents): - entries = [] - # Map of entrypath, revision for finding source of deleted - # revisions. - copyfrom = {} + changed, removed = set(), set() copies = {} new_module, revnum = self.revsplit(rev)[1:] @@ -621,12 +610,14 @@ self.module = new_module self.reparent(self.module) - for path, ent in paths: + for i, (path, ent) in enumerate(paths): + self.ui.progress(_('scanning paths'), i, item=path, + total=len(paths)) entrypath = self.getrelpath(path) kind = self._checkpath(entrypath, revnum) if kind == svn.core.svn_node_file: - entries.append(self.recode(entrypath)) + changed.add(self.recode(entrypath)) if not ent.copyfrom_path or not parents: continue # Copy sources not in parent revisions cannot be @@ -644,54 +635,39 @@ self.ui.debug("gone from %s\n" % ent.copyfrom_rev) pmodule, prevnum = self.revsplit(parents[0])[1:] parentpath = pmodule + "/" + entrypath - self.ui.debug("entry %s\n" % parentpath) - - # We can avoid the reparent calls if the module has - # not changed but it probably does not worth the pain. - prevmodule = self.reparent('') - fromkind = svn.ra.check_path(self.ra, parentpath.strip('/'), - prevnum) - self.reparent(prevmodule) + fromkind = self._checkpath(entrypath, prevnum, pmodule) if fromkind == svn.core.svn_node_file: - entries.append(self.recode(entrypath)) + removed.add(self.recode(entrypath)) elif fromkind == svn.core.svn_node_dir: - if ent.action == 'C': - children = self._find_children(path, prevnum) - else: - oroot = parentpath.strip('/') - nroot = path.strip('/') - children = self._find_children(oroot, prevnum) - children = [s.replace(oroot, nroot) for s in children] - - for child in children: - childpath = self.getrelpath("/" + child, pmodule) - if not childpath: - continue - if childpath in copies: - del copies[childpath] - entries.append(childpath) + oroot = parentpath.strip('/') + nroot = path.strip('/') + children = self._iterfiles(oroot, prevnum) + for childpath in children: + childpath = childpath.replace(oroot, nroot) + childpath = self.getrelpath("/" + childpath, pmodule) + if childpath: + removed.add(self.recode(childpath)) else: self.ui.debug('unknown path in revision %d: %s\n' % \ (revnum, path)) - elif kind == svn.core.svn_node_dir: - # If the directory just had a prop change, - # then we shouldn't need to look for its children. + elif kind == svn.core.svn_node_dir: if ent.action == 'M': + # If the directory just had a prop change, + # then we shouldn't need to look for its children. continue + elif ent.action == 'R' and parents: + # If a directory is replacing a file, mark the previous + # file as deleted + pmodule, prevnum = self.revsplit(parents[0])[1:] + pkind = self._checkpath(entrypath, prevnum, pmodule) + if pkind == svn.core.svn_node_file: + removed.add(self.recode(entrypath)) - children = sorted(self._find_children(path, revnum)) - for child in children: - # Can we move a child directory and its - # parent in the same commit? (probably can). Could - # cause problems if instead of revnum -1, - # we have to look in (copyfrom_path, revnum - 1) - entrypath = self.getrelpath("/" + child) - if entrypath: - # Need to filter out directories here... - kind = self._checkpath(entrypath, revnum) - if kind != svn.core.svn_node_dir: - entries.append(self.recode(entrypath)) + for childpath in self._iterfiles(path, revnum): + childpath = self.getrelpath("/" + childpath) + if childpath: + changed.add(self.recode(childpath)) # Handle directory copies if not ent.copyfrom_path or not parents: @@ -704,20 +680,20 @@ copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule) if not copyfrompath: continue - copyfrom[path] = ent self.ui.debug("mark %s came from %s:%d\n" % (path, copyfrompath, ent.copyfrom_rev)) - children = self._find_children(ent.copyfrom_path, ent.copyfrom_rev) - children.sort() - for child in children: - entrypath = self.getrelpath("/" + child, pmodule) - if not entrypath: + children = self._iterfiles(ent.copyfrom_path, ent.copyfrom_rev) + for childpath in children: + childpath = self.getrelpath("/" + childpath, pmodule) + if not childpath: continue - copytopath = path + entrypath[len(copyfrompath):] + copytopath = path + childpath[len(copyfrompath):] copytopath = self.getrelpath(copytopath) - copies[self.recode(copytopath)] = self.recode(entrypath) + copies[self.recode(copytopath)] = self.recode(childpath) - return (list(set(entries)), copies) + self.ui.progress(_('scanning paths'), None) + changed.update(removed) + return (list(changed), removed, copies) def _fetch_revisions(self, from_revnum, to_revnum): if from_revnum < to_revnum: @@ -844,8 +820,10 @@ raise util.Abort(_('svn: branch has no revision %s') % to_revnum) raise - def _getfile(self, file, rev): + def getfile(self, file, rev): # TODO: ra.get_file transmits the whole file instead of diffs. + if file in self.removed: + raise IOError() mode = '' try: new_module, revnum = self.revsplit(rev)[1:] @@ -874,12 +852,14 @@ data = data[len(link_prefix):] return data, mode - def _find_children(self, path, revnum): + def _iterfiles(self, path, revnum): + """Enumerate all files in path at revnum, recursively.""" path = path.strip('/') pool = Pool() rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/') - return ['%s/%s' % (path, x) for x in - svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool).keys()] + entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool) + return ((path + '/' + p) for p, e in entries.iteritems() + if e.kind == svn.core.svn_node_file) def getrelpath(self, path, module=None): if module is None: @@ -901,11 +881,18 @@ self.ui.debug('%r is not under %r, ignoring\n' % (path, module)) return None - def _checkpath(self, path, revnum): - # ra.check_path does not like leading slashes very much, it leads - # to PROPFIND subversion errors - return svn.ra.check_path(self.ra, path.strip('/'), revnum) - + def _checkpath(self, path, revnum, module=None): + if module is not None: + prevmodule = self.reparent('') + path = module + '/' + path + try: + # ra.check_path does not like leading slashes very much, it leads + # to PROPFIND subversion errors + return svn.ra.check_path(self.ra, path.strip('/'), revnum) + finally: + if module is not None: + self.reparent(prevmodule) + def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True, strict_node_history=False): # Normalize path names, svn >= 1.5 only wants paths relative to @@ -1107,12 +1094,11 @@ # Apply changes to working copy for f, v in files: try: - data = source.getfile(f, v) + data, mode = source.getfile(f, v) except IOError: self.delete.append(f) else: - e = source.getmode(f, v) - self.putfile(f, e, data) + self.putfile(f, mode, data) if f in copies: self.copies.append([copies[f], f]) files = [f[0] for f in files]
--- a/hgext/patchbomb.py Sun May 09 00:15:13 2010 +0200 +++ b/hgext/patchbomb.py Tue May 11 17:12:10 2010 -0500 @@ -34,6 +34,7 @@ to = recipient1, recipient2, ... cc = cc1, cc2, ... bcc = bcc1, bcc2, ... + reply-to = address1, address2, ... Use ``[patchbomb]`` as configuration section name if you need to override global ``[email]`` address settings. @@ -390,8 +391,9 @@ msgs = getpatchmsgs(list(getpatches(revs))) def getaddrs(opt, prpt=None, default=None): - if opts.get(opt): - return mail.addrlistencode(ui, opts.get(opt), _charsets, + addrs = opts.get(opt.replace('-', '_')) + if addrs: + return mail.addrlistencode(ui, addrs, _charsets, opts.get('test')) addrs = (ui.config('email', opt) or @@ -404,6 +406,7 @@ to = getaddrs('to', 'To') cc = getaddrs('cc', 'Cc', '') bcc = getaddrs('bcc') + replyto = getaddrs('reply-to') ui.write('\n') @@ -442,6 +445,8 @@ m['Cc'] = ', '.join(cc) if bcc: m['Bcc'] = ', '.join(bcc) + if replyto: + m['Reply-To'] = ', '.join(replyto) if opts.get('test'): ui.status(_('Displaying '), subj, ' ...\n') ui.flush() @@ -493,6 +498,7 @@ ('n', 'test', None, _('print messages that would be sent')), ('m', 'mbox', '', _('write messages to mbox file instead of sending them')), + ('', 'reply-to', [], _('email addresses replies should be sent to')), ('s', 'subject', '', _('subject of first message (intro or single patch)')), ('', 'in-reply-to', '',
--- a/mercurial/bundlerepo.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/bundlerepo.py Tue May 11 17:12:10 2010 -0500 @@ -166,7 +166,7 @@ localrepo.localrepository.__init__(self, ui, self._tempparent) if path: - self._url = 'bundle:' + path + '+' + bundlename + self._url = 'bundle:' + util.expandpath(path) + '+' + bundlename else: self._url = 'bundle:' + bundlename
--- a/mercurial/cmdutil.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/cmdutil.py Tue May 11 17:12:10 2010 -0500 @@ -396,6 +396,12 @@ if after: if not exists: + if rename: + ui.warn(_('%s: not recording move - %s does not exist\n') % + (relsrc, reltarget)) + else: + ui.warn(_('%s: not recording copy - %s does not exist\n') % + (relsrc, reltarget)) return elif not dryrun: try:
--- a/mercurial/context.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/context.py Tue May 11 17:12:10 2010 -0500 @@ -724,7 +724,7 @@ def findflag(ctx): mnode = ctx.changeset()[0] node, flag = self._repo.manifest.find(mnode, orig) - ff = self._repo.dirstate.flagfunc(lambda x: flag or None) + ff = self._repo.dirstate.flagfunc(lambda x: flag or '') try: return ff(path) except OSError: @@ -935,12 +935,16 @@ """get a file context from the working directory""" return self._filectxfn(self._repo, self, path) + def commit(self): + """commit context to the repo""" + return self._repo.commitctx(self) + class memfilectx(object): """memfilectx represents an in-memory file to commit. See memctx for more details. """ - def __init__(self, path, data, islink, isexec, copied): + def __init__(self, path, data, islink=False, isexec=False, copied=None): """ path is the normalized file path relative to repository root. data is the file content as a string.
--- a/mercurial/filemerge.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/filemerge.py Tue May 11 17:12:10 2010 -0500 @@ -7,7 +7,7 @@ from node import short from i18n import _ -import util, simplemerge, match +import util, simplemerge, match, error import os, tempfile, re, filecmp def _toolstr(ui, tool, part, default=""): @@ -16,6 +16,9 @@ def _toolbool(ui, tool, part, default=False): return ui.configbool("merge-tools", tool + "." + part, default) +def _toollist(ui, tool, part, default=[]): + return ui.configlist("merge-tools", tool + "." + part, default) + _internal = ['internal:' + s for s in 'fail local other merge prompt dump'.split()] @@ -176,7 +179,18 @@ ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca)) # do we attempt to simplemerge first? - if _toolbool(ui, tool, "premerge", not (binary or symlink)): + try: + premerge = _toolbool(ui, tool, "premerge", not (binary or symlink)) + except error.ConfigError: + premerge = _toolstr(ui, tool, "premerge").lower() + valid = 'keep'.split() + if premerge not in valid: + _valid = ', '.join(["'" + v + "'" for v in valid]) + raise error.ConfigError(_("%s.premerge not valid " + "('%s' is neither boolean nor %s)") % + (tool, premerge, _valid)) + + if premerge: r = simplemerge.simplemerge(ui, a, b, c, quiet=True) if not r: ui.debug(" premerge successful\n") @@ -184,7 +198,8 @@ os.unlink(b) os.unlink(c) return 0 - util.copyfile(back, a) # restore from backup and try again + if premerge != 'keep': + util.copyfile(back, a) # restore from backup and try again env = dict(HG_FILE=fd, HG_MY_NODE=short(mynode), @@ -211,11 +226,20 @@ lambda x: '"%s"' % util.localpath(replace[x.group()[1:]]), args) r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env) - if not r and _toolbool(ui, tool, "checkconflicts"): + if not r and (_toolbool(ui, tool, "checkconflicts") or + 'conflicts' in _toollist(ui, tool, "check")): if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data()): r = 1 - if not r and _toolbool(ui, tool, "checkchanged"): + checked = False + if 'prompt' in _toollist(ui, tool, "check"): + checked = True + if ui.promptchoice(_("was merge of '%s' successful (yn)?") % fd, + (_("&Yes"), _("&No")), 1): + r = 1 + + if not r and not checked and (_toolbool(ui, tool, "checkchanged") or + 'changed' in _toollist(ui, tool, "check")): if filecmp.cmp(repo.wjoin(fd), back): if ui.promptchoice(_(" output file %s appears unchanged\n" "was merge successful (yn)?") % fd,
--- a/mercurial/hg.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/hg.py Tue May 11 17:12:10 2010 -0500 @@ -15,8 +15,8 @@ import errno, os, shutil def _local(path): - return (os.path.isfile(util.drop_scheme('file', path)) and - bundlerepo or localrepo) + path = util.expandpath(util.drop_scheme('file', path)) + return (os.path.isfile(path) and bundlerepo or localrepo) def addbranchrevs(lrepo, repo, branches, revs): if not branches:
--- a/mercurial/httprepo.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/httprepo.py Tue May 11 17:12:10 2010 -0500 @@ -208,6 +208,12 @@ return util.chunkbuffer(zgenerator(f)) def unbundle(self, cg, heads, source): + '''Send cg (a readable file-like object representing the + changegroup to push, typically a chunkbuffer object) to the + remote server as a bundle. Return an integer response code: + non-zero indicates a successful push (see + localrepository.addchangegroup()), and zero indicates either + error or nothing to push.''' # have to stream bundle to a temp file because we do not have # http 1.1 chunked transfer.
--- a/mercurial/localrepo.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/localrepo.py Tue May 11 17:12:10 2010 -0500 @@ -25,7 +25,7 @@ def __init__(self, baseui, path=None, create=0): repo.repository.__init__(self) - self.root = os.path.realpath(path) + self.root = os.path.realpath(util.expandpath(path)) self.path = os.path.join(self.root, ".hg") self.origroot = path self.opener = util.opener(self.path) @@ -1507,6 +1507,13 @@ lock.release() def push(self, remote, force=False, revs=None): + '''Push outgoing changesets (limited by revs) from the current + repository to remote. Return an integer: + - 0 means HTTP error *or* nothing to push + - 1 means we pushed and remote head count is unchanged *or* + we have outgoing changesets but refused to push + - other values as described by addchangegroup() + ''' # there are two ways to push to remote repo: # # addchangegroup assumes local user can lock remote @@ -1521,11 +1528,18 @@ def prepush(self, remote, force, revs): '''Analyze the local and remote repositories and determine which - changesets need to be pushed to the remote. Return a tuple - (changegroup, remoteheads). changegroup is a readable file-like - object whose read() returns successive changegroup chunks ready to - be sent over the wire. remoteheads is the list of remote heads. - ''' + changesets need to be pushed to the remote. Return value depends + on circumstances: + + If we are not going to push anything, return a tuple (None, + outgoing) where outgoing is 0 if there are no outgoing + changesets and 1 if there are, but we refuse to push them + (e.g. would create new remote heads). + + Otherwise, return a tuple (changegroup, remoteheads), where + changegroup is a readable file-like object whose read() returns + successive changegroup chunks ready to be sent over the wire and + remoteheads is the list of remote heads.''' common = {} remote_heads = remote.heads() inc = self.findincoming(remote, common, remote_heads, force=force) @@ -1640,17 +1654,26 @@ return cg, remote_heads def push_addchangegroup(self, remote, force, revs): + '''Push a changegroup by locking the remote and sending the + addchangegroup command to it. Used for local and old SSH repos. + Return an integer: see push(). + ''' lock = remote.lock() try: ret = self.prepush(remote, force, revs) if ret[0] is not None: cg, remote_heads = ret + # here, we return an integer indicating remote head count change return remote.addchangegroup(cg, 'push', self.url()) + # and here we return 0 for "nothing to push" or 1 for + # "something to push but I refuse" return ret[1] finally: lock.release() def push_unbundle(self, remote, force, revs): + '''Push a changegroup by unbundling it on the remote. Used for new + SSH and HTTP repos. Return an integer: see push().''' # local repo finds heads on server, finds out what revs it # must push. once revs transferred, if server finds it has # different heads (someone else won commit/push race), server @@ -1661,7 +1684,10 @@ cg, remote_heads = ret if force: remote_heads = ['force'] + # ssh: return remote's addchangegroup() + # http: return remote's addchangegroup() or 0 for error return remote.unbundle(cg, remote_heads, 'push') + # as in push_addchangegroup() return ret[1] def changegroupinfo(self, nodes, source): @@ -2025,12 +2051,14 @@ return util.chunkbuffer(gengroup()) def addchangegroup(self, source, srctype, url, emptyok=False): - """add changegroup to repo. + """Add the changegroup returned by source.read() to this repo. + srctype is a string like 'push', 'pull', or 'unbundle'. url is + the URL of the repo where this changegroup is coming from. - return values: + Return an integer summarizing the change to this repo: - nothing changed or no source: 0 - more heads than before: 1+added heads (2..n) - - less heads than before: -1-removed heads (-2..-n) + - fewer heads than before: -1-removed heads (-2..-n) - number of heads stays the same: 1 """ def csmap(x):
--- a/mercurial/posix.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/posix.py Tue May 11 17:12:10 2010 -0500 @@ -259,6 +259,12 @@ except KeyError: return str(gid) +def groupmembers(name): + """Return the list of members of the group with the given + name, KeyError if the group does not exist. + """ + return list(grp.getgrnam(name).gr_mem) + def spawndetached(args): return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0), args[0], args)
--- a/mercurial/revlog.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/revlog.py Tue May 11 17:12:10 2010 -0500 @@ -444,7 +444,10 @@ i = '' try: f = self.opener(self.indexfile) - i = f.read(_prereadsize) + if "nonlazy" in getattr(self.opener, 'options', {}): + i = f.read() + else: + i = f.read(_prereadsize) if len(i) > 0: v = struct.unpack(versionformat, i[:4])[0] except IOError, inst:
--- a/mercurial/sshrepo.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/sshrepo.py Tue May 11 17:12:10 2010 -0500 @@ -217,6 +217,10 @@ return self.do_cmd("changegroupsubset", bases=bases, heads=heads) def unbundle(self, cg, heads, source): + '''Send cg (a readable file-like object representing the + changegroup to push, typically a chunkbuffer object) to the + remote server as a bundle. Return an integer indicating the + result of the push (see localrepository.addchangegroup()).''' d = self.call("unbundle", heads=' '.join(map(hex, heads))) if d: # remote may send "unsynced changes" @@ -242,6 +246,9 @@ self.abort(error.ResponseError(_("unexpected response:"), r)) def addchangegroup(self, cg, source, url): + '''Send a changegroup to the remote server. Return an integer + similar to unbundle(). DEPRECATED, since it requires locking the + remote.''' d = self.call("addchangegroup") if d: self.abort(error.RepoError(_("push refused: %s") % d))
--- a/mercurial/statichttprepo.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/statichttprepo.py Tue May 11 17:12:10 2010 -0500 @@ -77,6 +77,7 @@ return httprangereader(f, urlopener) return o + opener.options = {'nonlazy': 1} return opener class statichttprepository(localrepo.localrepository):
--- a/mercurial/windows.py Sun May 09 00:15:13 2010 +0200 +++ b/mercurial/windows.py Tue May 11 17:12:10 2010 -0500 @@ -363,6 +363,10 @@ # current line but on the new one. Keep room for it. return 79 +def groupmembers(name): + # Don't support groups on Windows for now + raise KeyError() + try: # override functions with win32 versions if possible from win32 import *
--- a/tests/svn/move.svndump Sun May 09 00:15:13 2010 +0200 +++ b/tests/svn/move.svndump Tue May 11 17:12:10 2010 -0500 @@ -1,6 +1,6 @@ SVN-fs-dump-format-version: 2 -UUID: 9de99ecc-876b-46e5-bc59-bff9b2b58b1e +UUID: 7d15f7c2-5863-4c16-aa2a-3418b1721d3a Revision-number: 0 Prop-content-length: 56 @@ -9,7 +9,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:26.678698Z +2010-05-09T13:02:37.336239Z PROPS-END Revision-number: 1 @@ -27,7 +27,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:27.278689Z +2010-05-09T13:02:37.372834Z PROPS-END Node-path: trunk @@ -124,7 +124,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:28.312955Z +2010-05-09T13:02:38.049068Z PROPS-END Node-path: trunk/a @@ -166,7 +166,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:29.183467Z +2010-05-09T13:02:39.044479Z PROPS-END Node-path: subproject @@ -195,7 +195,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:30.300975Z +2010-05-09T13:02:40.057804Z PROPS-END Node-path: subproject/trunk @@ -222,7 +222,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:31.354398Z +2010-05-09T13:02:41.058871Z PROPS-END Node-path: subproject/branches @@ -249,7 +249,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:32.121901Z +2010-05-09T13:02:42.046689Z PROPS-END Node-path: subproject/trunk/d1 @@ -278,7 +278,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:32.317815Z +2010-05-09T13:02:42.071413Z PROPS-END Node-path: subproject/trunk/d2 @@ -307,7 +307,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:33.418320Z +2010-05-09T13:02:43.062018Z PROPS-END Node-path: subproject/trunk/d1/b @@ -341,7 +341,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:34.126542Z +2010-05-09T13:02:44.047997Z PROPS-END Node-path: subproject/branches/d1 @@ -370,7 +370,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:34.436015Z +2010-05-09T13:02:44.086619Z PROPS-END Node-path: subproject/trunk/d @@ -397,7 +397,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:34.803189Z +2010-05-09T13:02:44.111550Z PROPS-END Node-path: subproject/trunk/d2 @@ -422,7 +422,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:36.531735Z +2010-05-09T13:02:45.067982Z PROPS-END Node-path: subproject/trunk/d3 @@ -484,7 +484,7 @@ K 8 svn:date V 27 -2009-06-21T14:32:38.281829Z +2010-05-09T13:02:47.061259Z PROPS-END Node-path: subproject/trunk/d3/d31 @@ -498,3 +498,72 @@ Node-copyfrom-path: subproject/trunk/d3 +Revision-number: 14 +Prop-content-length: 110 +Content-length: 110 + +K 7 +svn:log +V 9 +add d4old +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-05-09T13:02:49.063363Z +PROPS-END + +Node-path: subproject/trunk/d4old +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: subproject/trunk/d4old/g +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: f5302386464f953ed581edac03556e55 +Text-content-sha1: a5938ace3f424be1a26904781cdb06d55b614e6b +Content-length: 12 + +PROPS-END +g + + +Revision-number: 15 +Prop-content-length: 125 +Content-length: 125 + +K 7 +svn:log +V 23 +rename d4old into d4new +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-05-09T13:02:51.047304Z +PROPS-END + +Node-path: subproject/trunk/d4new +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 14 +Node-copyfrom-path: subproject/trunk/d4old + + +Node-path: subproject/trunk/d4old +Node-action: delete + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/svn/replace.svndump Tue May 11 17:12:10 2010 -0500 @@ -0,0 +1,241 @@ +SVN-fs-dump-format-version: 2 + +UUID: 4a895937-439c-4e56-b7b0-fa1c8acc0c20 + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2010-05-09T14:57:31.007802Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 108 +Content-length: 108 + +K 7 +svn:log +V 7 +initial +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-05-09T14:57:32.094732Z +PROPS-END + +Node-path: branches +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk/a +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: 60b725f10c9c85c70d97880dfe8191b3 +Text-content-sha1: 3f786850e387550fdab836ed7e6dc881de23001b +Content-length: 12 + +PROPS-END +a + + +Node-path: trunk/d +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk/d/b +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: 3b5d5c3712955042212316173ccf37be +Text-content-sha1: 89e6c98d92887913cadf06b2adb97f26cde4849b +Content-length: 12 + +PROPS-END +b + + +Node-path: trunk/dlink +Node-kind: file +Node-action: add +Prop-content-length: 33 +Text-content-length: 6 +Text-content-md5: cca56829f18345718a4980bb02b6d8c3 +Text-content-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49 +Content-length: 39 + +K 11 +svn:special +V 1 +* +PROPS-END +link d + +Node-path: trunk/dlink2 +Node-kind: file +Node-action: add +Prop-content-length: 33 +Text-content-length: 6 +Text-content-md5: cca56829f18345718a4980bb02b6d8c3 +Text-content-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49 +Content-length: 39 + +K 11 +svn:special +V 1 +* +PROPS-END +link d + +Node-path: trunk/dlink3 +Node-kind: file +Node-action: add +Prop-content-length: 33 +Text-content-length: 6 +Text-content-md5: cca56829f18345718a4980bb02b6d8c3 +Text-content-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49 +Content-length: 39 + +K 11 +svn:special +V 1 +* +PROPS-END +link d + +Revision-number: 2 +Prop-content-length: 117 +Content-length: 117 + +K 7 +svn:log +V 15 +clobber symlink +K 10 +svn:author +V 7 +pmezard +K 8 +svn:date +V 27 +2010-05-09T14:57:33.071117Z +PROPS-END + +Node-path: trunk/dlink3 +Node-kind: file +Node-action: change +Prop-content-length: 10 +Text-content-length: 2 +Text-content-md5: e29311f6f1bf1af907f9ef9f44b8328b +Text-content-sha1: e983f374794de9c64e3d1c1de1d490c0756eeeff +Content-length: 12 + +PROPS-END +d + + +Revision-number: 3 +Prop-content-length: 106 +Content-length: 106 + +K 7 +svn:log +V 8 +clobber1 +K 10 +svn:author +V 4 +evil +K 8 +svn:date +V 27 +2010-05-09T14:57:35.268057Z +PROPS-END + +Node-path: trunk/a +Node-kind: dir +Node-action: delete + +Node-path: trunk/a +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 2 +Node-copyfrom-path: trunk/d + + + + +Node-path: trunk/dlink +Node-kind: dir +Node-action: delete + +Node-path: trunk/dlink +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 2 +Node-copyfrom-path: trunk/d + + + + +Revision-number: 4 +Prop-content-length: 106 +Content-length: 106 + +K 7 +svn:log +V 8 +clobber2 +K 10 +svn:author +V 4 +evil +K 8 +svn:date +V 27 +2010-05-09T14:57:35.521816Z +PROPS-END + +Node-path: trunk/dlink3 +Node-kind: file +Node-action: delete + +Node-path: trunk/dlink3 +Node-kind: file +Node-action: add +Node-copyfrom-rev: 3 +Node-copyfrom-path: trunk/dlink2 +Text-copy-source-md5: cca56829f18345718a4980bb02b6d8c3 +Text-copy-source-sha1: 7c54cc5d472b78c94a04382df34b0f4f0f4f2d49 + + + +
--- a/tests/svn/svndump-move.sh Sun May 09 00:15:13 2010 +0200 +++ b/tests/svn/svndump-move.sh Tue May 11 17:12:10 2010 -0500 @@ -68,6 +68,16 @@ svn copy subproject/trunk/d3 subproject/trunk/d4 svn rm subproject/trunk/d3/d31 svn ci -m "copy dir and remove subdir" + +# Test directory moves +svn up +mkdir -p subproject/trunk/d4old +echo g > subproject/trunk/d4old/g +svn add subproject/trunk/d4old +svn ci -m "add d4old" +svn mv subproject/trunk/d4old subproject/trunk/d4new +svn ci -m "rename d4old into d4new" + cd .. svnadmin dump svn-repo > ../move.svndump \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/svn/svndump-replace.sh Tue May 11 17:12:10 2010 -0500 @@ -0,0 +1,55 @@ +#!/bin/sh + +RSVN="`pwd`/rsvn.py" +export PATH=/bin:/usr/bin +mkdir temp +cd temp + +svnadmin create repo +svn co file://`pwd`/repo wc + +cd wc +mkdir trunk branches +cd trunk +echo a > a +mkdir d +echo b > d/b +ln -s d dlink +ln -s d dlink2 +ln -s d dlink3 +cd .. +svn add * +svn ci -m 'initial' +# Clobber symlink with file with similar content +cd trunk +ls -Alh +readlink dlink3 > dlink3tmp +rm dlink3 +mv dlink3tmp dlink3 +svn propdel svn:special dlink3 +svn ci -m 'clobber symlink' +cd .. +svn up + +# Clobber files and symlink with directories +cd .. +cat > clobber.rsvn <<EOF +rdelete trunk/a +rdelete trunk/dlink +rcopy trunk/d trunk/a +rcopy trunk/d trunk/dlink +EOF + +python $RSVN --message=clobber1 --username=evil `pwd`/repo < clobber.rsvn + +# Clobber non-symlink with symlink with same content (kudos openwrt) +cat > clobber.rsvn <<EOF +rdelete trunk/dlink3 +rcopy trunk/dlink2 trunk/dlink3 +EOF + +python $RSVN --message=clobber2 --username=evil `pwd`/repo < clobber.rsvn + +svn log -v file://`pwd`/repo + +svnadmin dump repo > ../replace.svndump
--- a/tests/test-acl Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-acl Tue May 11 17:12:10 2010 -0500 @@ -7,7 +7,7 @@ echo "Pushing as user $user" echo 'hgrc = """' - sed -e 1,2d b/.hg/hgrc | grep -v "$HGTMP" + sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py echo '"""' if test -f acl.config; then echo 'acl.config = """' @@ -165,4 +165,12 @@ echo "@group is allowed inside anything but foo/Bar/" do_push fred +echo 'Invalid group' +# Disable the fakegroups trick to get real failures +grep -v fakegroups $config > config.tmp +mv config.tmp $config +echo '[acl.allow]' >> $config +echo "** = @unlikelytoexist" >> $config +do_push fred 2>&1 | grep unlikelytoexist +true
--- a/tests/test-acl.out Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-acl.out Tue May 11 17:12:10 2010 -0500 @@ -1557,3 +1557,8 @@ no rollback information available 0:6675d58eff77 +Invalid group +** = @unlikelytoexist +acl: "unlikelytoexist" not defined in [acl.groups] +error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined +abort: group 'unlikelytoexist' is undefined
--- a/tests/test-bookmarks Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-bookmarks Tue May 11 17:12:10 2010 -0500 @@ -15,7 +15,8 @@ hg bookmarks echo % list bookmarks with color -hg --config extensions.color= bookmarks --color=always +hg --config extensions.color= --config color.mode=ansi \ + bookmarks --color=always echo a > a hg add a
--- a/tests/test-bookmarks-current Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-bookmarks-current Tue May 11 17:12:10 2010 -0500 @@ -18,7 +18,8 @@ hg bookmark echo % list bookmarks with color -hg --config extensions.color= bookmark --color=always +hg --config extensions.color= --config color.mode=ansi \ + bookmark --color=always echo % update to bookmark X hg update X
--- a/tests/test-churn Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-churn Tue May 11 17:12:10 2010 -0500 @@ -53,7 +53,8 @@ hg ci -Am "removed d/g/f2.txt" -u user1 -d 14:00 d/g/f2.txt hg churn --diffstat echo % churn --diffstat with color -hg --config extensions.color= churn --diffstat --color=always +hg --config extensions.color= churn --config color.mode=ansi \ + --diffstat --color=always echo % changeset number churn hg churn -c
--- a/tests/test-convert-svn-move Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-convert-svn-move Tue May 11 17:12:10 2010 -0500 @@ -28,5 +28,43 @@ cd A-hg hg glog --template '{rev} {desc|firstline} files: {files}\n' +echo '% check move copy records' +hg st --rev 12:13 --copies +echo '% check branches' hg branches | sed 's/:.*/:/' cd .. + +mkdir test-replace +cd test-replace +svnadmin create svn-repo +cat "$TESTDIR/svn/replace.svndump" | svnadmin load svn-repo > /dev/null + +echo '% convert files being replaced by directories' +hg convert svn-repo hg-repo +cd hg-repo +echo '% manifest before' +hg -v manifest -r 1 +echo '% manifest after clobber1' +hg -v manifest -r 2 +echo '% manifest after clobber2' +hg -v manifest -r 3 +echo '% try updating' +hg up -qC default +cd .. + +echo '% test convert progress bar' + +echo "progress=" >> $HGRCPATH +echo "[progress]" >> $HGRCPATH +echo "assume-tty=1" >> $HGRCPATH +echo "delay=0" >> $HGRCPATH +echo "refresh=0" >> $HGRCPATH + +cat > filtercr.py <<EOF +import sys, re +for line in sys.stdin: + line = re.sub(r'\r+[^\n]', lambda m: '\n' + m.group()[-1:], line) + sys.stdout.write(line) +EOF + +hg convert svn-repo hg-progress 2>&1 | python filtercr.py
--- a/tests/test-convert-svn-move.out Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-convert-svn-move.out Tue May 11 17:12:10 2010 -0500 @@ -3,18 +3,24 @@ scanning source... sorting... converting... -11 createtrunk -10 moved1 -9 moved1 -8 moved2 -7 changeb and rm d2 -6 changeb and rm d2 -5 moved1again -4 moved1again -3 copyfilefrompast -2 copydirfrompast -1 add d3 -0 copy dir and remove subdir +13 createtrunk +12 moved1 +11 moved1 +10 moved2 +9 changeb and rm d2 +8 changeb and rm d2 +7 moved1again +6 moved1again +5 copyfilefrompast +4 copydirfrompast +3 add d3 +2 copy dir and remove subdir +1 add d4old +0 rename d4old into d4new +o 13 rename d4old into d4new files: d4new/g d4old/g +| +o 12 add d4old files: d4old/g +| o 11 copy dir and remove subdir files: d3/d31/e d4/d31/e d4/f | o 10 add d3 files: d3/d31/e d3/f @@ -39,5 +45,79 @@ | o 0 createtrunk files: -default 11: +% check move copy records +A d4new/g + d4old/g +R d4old/g +% check branches +default 13: d1 6: +% convert files being replaced by directories +initializing destination hg-repo repository +scanning source... +sorting... +converting... +3 initial +2 clobber symlink +1 clobber1 +0 clobber2 +% manifest before +644 a +644 d/b +644 @ dlink +644 @ dlink2 +644 dlink3 +% manifest after clobber1 +644 a/b +644 d/b +644 dlink/b +644 @ dlink2 +644 dlink3 +% manifest after clobber2 +644 a/b +644 d/b +644 dlink/b +644 @ dlink2 +644 @ dlink3 +% try updating +% test convert progress bar + +scanning [ <=> ] 1 +scanning [ <=> ] 2 +scanning [ <=> ] 3 +scanning [ <=> ] 4 + +converting [ ] 0/4 +retrieving file [==========> ] 1/5 +retrieving file [=====================> ] 2/5 +retrieving file [=================================> ] 3/5 +retrieving file [============================================> ] 4/5 +retrieving file [========================================================>] 5/5 + +converting [==============> ] 1/4 +scanning paths [ ] 0/1 + +retrieving file [========================================================>] 1/1 + +converting [==============================> ] 2/4 +scanning paths [ ] 0/2 +scanning paths [============================> ] 1/2 + +retrieving file [=============> ] 1/4 +retrieving file [===========================> ] 2/4 +retrieving file [=========================================> ] 3/4 +retrieving file [========================================================>] 4/4 + +converting [=============================================> ] 3/4 +scanning paths [ ] 0/1 + +retrieving file [========================================================>] 1/1 + +initializing destination hg-progress repository +scanning source... +sorting... +converting... +3 initial +2 clobber symlink +1 clobber1 +0 clobber2
--- a/tests/test-copy2 Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-copy2 Tue May 11 17:12:10 2010 -0500 @@ -19,6 +19,9 @@ hg st -A hg commit -m1 +echo "# copy --after to a nonexistant target filename" +hg cp -A foo dummy + echo "# dry-run; should show that foo is clean" hg copy --dry-run foo bar hg st -A
--- a/tests/test-copy2.out Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-copy2.out Tue May 11 17:12:10 2010 -0500 @@ -11,6 +11,8 @@ # should print a warning that this is not a real copy; foo is added bar has not been committed yet, so no copy data will be stored for foo. A foo +# copy --after to a nonexistant target filename +foo: not recording copy - dummy does not exist # dry-run; should show that foo is clean C foo # should show copy
--- a/tests/test-grep Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-grep Tue May 11 17:12:10 2010 -0500 @@ -22,7 +22,8 @@ echo % simple hg grep port port echo % simple with color -hg --config extensions.color= grep --color=always port port +hg --config extensions.color= grep --config color.mode=ansi \ + --color=always port port echo % all hg grep --traceback --all -nu port port echo % other
--- a/tests/test-log Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-log Tue May 11 17:12:10 2010 -0500 @@ -119,7 +119,8 @@ hg log -d -1 echo '% log -p -l2 --color=always' -hg --config extensions.color= log -p -l2 --color=always +hg --config extensions.color= --config color.mode=ansi \ + log -p -l2 --color=always echo '% log -r tip --stat' hg log -r tip --stat
--- a/tests/test-mq-guards Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-mq-guards Tue May 11 17:12:10 2010 -0500 @@ -100,7 +100,8 @@ echo % list patches and guards hg qguard -l echo % list patches and guards with color -hg --config extensions.color= qguard -l --color=always +hg --config extensions.color= qguard --config color.mode=ansi \ + -l --color=always echo % list series hg qseries -v echo % list guards
--- a/tests/test-patchbomb Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-patchbomb Tue May 11 17:12:10 2010 -0500 @@ -135,6 +135,14 @@ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \ -r 0:1 | fixheaders +echo "% test reply-to via config" +hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \ + --config patchbomb.reply-to='baz@example.com' | fixheaders + +echo "% test reply-to via command line" +hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \ + --reply-to baz --reply-to fred | fixheaders + echo "% tagging csets" hg tag -r0 zero zero.foo hg tag -r1 one one.patch
--- a/tests/test-patchbomb.out Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-patchbomb.out Tue May 11 17:12:10 2010 -0500 @@ -1062,6 +1062,68 @@ @@ -0,0 +1,1 @@ +b +% test reply-to via config +This patch series consists of 1 patches. + + +Displaying [PATCH] test ... +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [PATCH] test +X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f +Message-Id: <ff2c9fa2018b15fa74b3.60@ +User-Agent: Mercurial-patchbomb +Date: Thu, 01 Jan 1970 00:01:00 +0000 +From: quux +To: foo +Cc: bar +Reply-To: baz@example.com + +# HG changeset patch +# User test +# Date 3 0 +# Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f +# Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 +c + +diff -r 97d72e5f12c7 -r ff2c9fa2018b c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/c Thu Jan 01 00:00:03 1970 +0000 +@@ -0,0 +1,1 @@ ++c + +% test reply-to via command line +This patch series consists of 1 patches. + + +Displaying [PATCH] test ... +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [PATCH] test +X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f +Message-Id: <ff2c9fa2018b15fa74b3.60@ +User-Agent: Mercurial-patchbomb +Date: Thu, 01 Jan 1970 00:01:00 +0000 +From: quux +To: foo +Cc: bar +Reply-To: baz, fred + +# HG changeset patch +# User test +# Date 3 0 +# Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f +# Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9 +c + +diff -r 97d72e5f12c7 -r ff2c9fa2018b c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/c Thu Jan 01 00:00:03 1970 +0000 +@@ -0,0 +1,1 @@ ++c + % tagging csets % test inline for single named patch This patch series consists of 1 patches.
--- a/tests/test-rename Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-rename Tue May 11 17:12:10 2010 -0500 @@ -23,6 +23,9 @@ hg update -C rm d2/c +echo "# rename --after a single file to a nonexistant target filename" +hg rename --after d1/a dummy + echo "# move a single file to an existing directory" hg rename d1/d11/a1 d2 hg status -C
--- a/tests/test-rename.out Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-rename.out Tue May 11 17:12:10 2010 -0500 @@ -8,6 +8,8 @@ d1/d11/a1 R d1/d11/a1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved +# rename --after a single file to a nonexistant target filename +d1/a: not recording move - dummy does not exist # move a single file to an existing directory A d2/a1 d1/d11/a1 @@ -170,6 +172,8 @@ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved # move --after some files under d1 to d2/d21 (glob) moving d1/a to d2/d21/a +d1/b: not recording move - d2/d21/b does not exist +d1/ba: not recording move - d2/d21/ba does not exist moving d1/d11/a1 to d2/d21/a1 A d2/d21/a d1/a
--- a/tests/test-schemes Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-schemes Tue May 11 17:12:10 2010 -0500 @@ -7,6 +7,7 @@ [schemes] l = http://localhost:$HGPORT/ parts = http://{1}:$HGPORT/ +z = file:\$PWD/ EOF hg init test @@ -22,5 +23,8 @@ echo % check that {1} syntax works hg incoming --debug parts://localhost | sed 's/[0-9]//g' +echo % check that paths are expanded +PWD=`pwd` hg incoming z:// + echo % errors cat errors.log
--- a/tests/test-schemes.out Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-schemes.out Tue May 11 17:12:10 2010 -0500 @@ -9,4 +9,8 @@ sending heads command searching for changes no changes found +% check that paths are expanded +comparing with z:// +searching for changes +no changes found % errors
--- a/tests/test-status-color Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-status-color Tue May 11 17:12:10 2010 -0500 @@ -2,6 +2,8 @@ echo "[extensions]" >> $HGRCPATH echo "color=" >> $HGRCPATH +echo "[color]" >> $HGRCPATH +echo "mode=ansi" >> $HGRCPATH hg init repo1 cd repo1
--- a/tests/test-subrepo-svn Sun May 09 00:15:13 2010 +0200 +++ b/tests/test-subrepo-svn Tue May 11 17:12:10 2010 -0500 @@ -63,7 +63,8 @@ echo % change file in svn and hg, commit echo a >> a echo alpha >> s/alpha -hg commit -m 'Message!' | sed "$filterexternal" +hg commit -m 'Message!' | sed "$filterexternal" \ + | sed 's:Sending.*s/alpha:Sending s/alpha:g' hg debugsub | sed "$filterpath" echo