--- a/contrib/dumprevlog Thu Jun 26 13:37:47 2008 -0700
+++ b/contrib/dumprevlog Sat Jun 28 09:28:01 2008 +0200
@@ -12,7 +12,7 @@
binopen = lambda fn: open(fn, 'rb')
r = revlog.revlog(binopen, f)
print "file:", f
- for i in xrange(r.count()):
+ for i in r:
n = r.node(i)
p = r.parents(n)
d = r.revision(n)
--- a/hgext/acl.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/acl.py Sat Jun 28 09:28:01 2008 +0200
@@ -91,7 +91,7 @@
def check(self, node):
'''return if access allowed, raise exception if not.'''
- files = self.repo.changectx(node).files()
+ files = self.repo[node].files()
if self.deniable:
for f in files:
if self.deny(f):
@@ -118,7 +118,5 @@
ui.debug(_('acl: changes have source "%s" - skipping\n') % source)
return
- start = repo.changelog.rev(bin(node))
- end = repo.changelog.count()
- for rev in xrange(start, end):
+ for rev in xrange(repo[node].rev(), len(repo)):
c.check(repo.changelog.node(rev))
--- a/hgext/bugzilla.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/bugzilla.py Sat Jun 28 09:28:01 2008 +0200
@@ -99,9 +99,7 @@
def filter_real_bug_ids(self, ids):
'''filter not-existing bug ids from list.'''
self.run('select bug_id from bugs where bug_id in %s' % buglist(ids))
- ids = [c[0] for c in self.cursor.fetchall()]
- ids.sort()
- return ids
+ return util.sort([c[0] for c in self.cursor.fetchall()])
def filter_unknown_bug_ids(self, node, ids):
'''filter bug ids from list that already refer to this changeset.'''
@@ -114,9 +112,7 @@
self.ui.status(_('bug %d already knows about changeset %s\n') %
(id, short(node)))
unknown.pop(id, None)
- ids = unknown.keys()
- ids.sort()
- return ids
+ return util.sort(unknown.keys())
def notify(self, ids):
'''tell bugzilla to send mail.'''
@@ -300,7 +296,7 @@
hooktype)
try:
bz = bugzilla(ui, repo)
- ctx = repo.changectx(node)
+ ctx = repo[node]
ids = bz.find_bug_ids(ctx)
if ids:
for id in ids:
--- a/hgext/children.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/children.py Sat Jun 28 09:28:01 2008 +0200
@@ -25,7 +25,7 @@
if file_:
ctx = repo.filectx(file_, changeid=rev)
else:
- ctx = repo.changectx(rev)
+ ctx = repo[rev]
displayer = cmdutil.show_changeset(ui, repo, opts)
for node in [cp.node() for cp in ctx.children()]:
--- a/hgext/churn.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/churn.py Sat Jun 28 09:28:01 2008 +0200
@@ -7,7 +7,7 @@
'''allow graphing the number of lines changed per contributor'''
from mercurial.i18n import gettext as _
-from mercurial import mdiff, cmdutil, util, node
+from mercurial import patch, cmdutil, util, node
import os, sys
def get_tty_width():
@@ -31,98 +31,41 @@
pass
return 80
-def __gather(ui, repo, node1, node2):
- def dirtywork(f, mmap1, mmap2):
- lines = 0
-
- to = mmap1 and repo.file(f).read(mmap1[f]) or None
- tn = mmap2 and repo.file(f).read(mmap2[f]) or None
-
- diff = mdiff.unidiff(to, "", tn, "", f, f).split("\n")
-
- for line in diff:
- if not line:
- continue # skip EOF
- if line.startswith(" "):
- continue # context line
- if line.startswith("--- ") or line.startswith("+++ "):
- continue # begining of diff
- if line.startswith("@@ "):
- continue # info line
-
- # changed lines
- lines += 1
-
- return lines
-
- ##
-
- lines = 0
-
- changes = repo.status(node1, node2)[:5]
-
- modified, added, removed, deleted, unknown = changes
-
- who = repo.changelog.read(node2)[1]
- who = util.email(who) # get the email of the person
-
- mmap1 = repo.manifest.read(repo.changelog.read(node1)[0])
- mmap2 = repo.manifest.read(repo.changelog.read(node2)[0])
- for f in modified:
- lines += dirtywork(f, mmap1, mmap2)
-
- for f in added:
- lines += dirtywork(f, None, mmap2)
-
- for f in removed:
- lines += dirtywork(f, mmap1, None)
-
- for f in deleted:
- lines += dirtywork(f, mmap1, mmap2)
-
- for f in unknown:
- lines += dirtywork(f, mmap1, mmap2)
-
- return (who, lines)
-
-def gather_stats(ui, repo, amap, revs=None, progress=False):
+def countrevs(ui, repo, amap, revs, progress=False):
stats = {}
-
- cl = repo.changelog
-
+ count = pct = 0
if not revs:
- revs = range(0, cl.count())
-
- nr_revs = len(revs)
- cur_rev = 0
+ revs = range(len(repo))
for rev in revs:
- cur_rev += 1 # next revision
-
- node2 = cl.node(rev)
- node1 = cl.parents(node2)[0]
-
- if cl.parents(node2)[1] != node.nullid:
+ ctx2 = repo[rev]
+ parents = ctx2.parents()
+ if len(parents) > 1:
ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
continue
- who, lines = __gather(ui, repo, node1, node2)
+ ctx1 = parents[0]
+ lines = 0
+ ui.pushbuffer()
+ patch.diff(repo, ctx1.node(), ctx2.node())
+ diff = ui.popbuffer()
- # remap the owner if possible
- if who in amap:
- ui.note("using '%s' alias for '%s'\n" % (amap[who], who))
- who = amap[who]
+ for l in diff.split('\n'):
+ if (l.startswith("+") and not l.startswith("+++ ") or
+ l.startswith("-") and not l.startswith("--- ")):
+ lines += 1
- if not who in stats:
- stats[who] = 0
- stats[who] += lines
-
- ui.note("rev %d: %d lines by %s\n" % (rev, lines, who))
+ user = util.email(ctx2.user())
+ user = amap.get(user, user) # remap
+ stats[user] = stats.get(user, 0) + lines
+ ui.debug("rev %d: %d lines by %s\n" % (rev, lines, user))
if progress:
- nr_revs = max(nr_revs, 1)
- if int(100.0*(cur_rev - 1)/nr_revs) < int(100.0*cur_rev/nr_revs):
- ui.write("\rGenerating stats: %d%%" % (int(100.0*cur_rev/nr_revs),))
+ count += 1
+ newpct = int(100.0 * count / max(len(revs), 1))
+ if pct < newpct:
+ pct = newpct
+ ui.write("\rGenerating stats: %d%%" % pct)
sys.stdout.flush()
if progress:
@@ -139,61 +82,32 @@
<alias email> <actual email>'''
def pad(s, l):
- if len(s) < l:
- return s + " " * (l-len(s))
- return s[0:l]
-
- def graph(n, maximum, width, char):
- maximum = max(1, maximum)
- n = int(n * width / float(maximum))
-
- return char * (n)
-
- def get_aliases(f):
- aliases = {}
-
- for l in f.readlines():
- l = l.strip()
- alias, actual = l.split()
- aliases[alias] = actual
-
- return aliases
+ return (s + " " * l)[:l]
amap = {}
aliases = opts.get('aliases')
if aliases:
- try:
- f = open(aliases,"r")
- except OSError, e:
- print "Error: " + e
- return
+ for l in open(aliases, "r"):
+ l = l.strip()
+ alias, actual = l.split()
+ amap[alias] = actual
- amap = get_aliases(f)
- f.close()
-
- revs = [int(r) for r in cmdutil.revrange(repo, opts['rev'])]
- revs.sort()
- stats = gather_stats(ui, repo, amap, revs, opts.get('progress'))
+ revs = util.sort([int(r) for r in cmdutil.revrange(repo, opts['rev'])])
+ stats = countrevs(ui, repo, amap, revs, opts.get('progress'))
+ if not stats:
+ return
- # make a list of tuples (name, lines) and sort it in descending order
- ordered = stats.items()
- if not ordered:
- return
- ordered.sort(lambda x, y: cmp(y[1], x[1]))
- max_churn = ordered[0][1]
+ stats = util.sort([(-l, u, l) for u,l in stats.items()])
+ maxchurn = float(max(1, stats[0][2]))
+ maxuser = max([len(u) for k, u, l in stats])
- tty_width = get_tty_width()
- ui.note(_("assuming %i character terminal\n") % tty_width)
- tty_width -= 1
-
- max_user_width = max([len(user) for user, churn in ordered])
+ ttywidth = get_tty_width()
+ ui.debug(_("assuming %i character terminal\n") % ttywidth)
+ width = ttywidth - maxuser - 2 - 6 - 2 - 2
- graph_width = tty_width - max_user_width - 1 - 6 - 2 - 2
-
- for user, churn in ordered:
- print "%s %6d %s" % (pad(user, max_user_width),
- churn,
- graph(churn, max_churn, graph_width, '*'))
+ for k, user, churn in stats:
+ print "%s %6d %s" % (pad(user, maxuser), churn,
+ "*" * int(churn * width / maxchurn))
cmdtable = {
"churn":
--- a/hgext/convert/cvs.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/convert/cvs.py Sat Jun 28 09:28:01 2008 +0200
@@ -337,10 +337,7 @@
def getchanges(self, rev):
self.modecache = {}
- files = self.files[rev]
- cl = files.items()
- cl.sort()
- return (cl, {})
+ return util.sort(self.files[rev].items()), {}
def getcommit(self, rev):
return self.changeset[rev]
@@ -349,7 +346,4 @@
return self.tags
def getchangedfiles(self, rev, i):
- files = self.files[rev].keys()
- files.sort()
- return files
-
+ return util.sort(self.files[rev].keys())
--- a/hgext/convert/cvsps.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/convert/cvsps.py Sat Jun 28 09:28:01 2008 +0200
@@ -297,8 +297,7 @@
if store:
# clean up the results and save in the log.
store = False
- e.tags = [scache(x) for x in tags.get(e.revision, [])]
- e.tags.sort()
+ e.tags = util.sort([scache(x) for x in tags.get(e.revision, [])])
e.comment = scache('\n'.join(e.comment))
revn = len(e.revision)
@@ -468,9 +467,7 @@
for tag in e.tags:
tags[tag] = True
# remember tags only if this is the latest changeset to have it
- tagnames = [tag for tag in tags if globaltags[tag] is c]
- tagnames.sort()
- c.tags = tagnames
+ c.tags = util.sort([tag for tag in tags if globaltags[tag] is c])
# Find parent changesets, handle {{mergetobranch BRANCHNAME}}
# by inserting dummy changesets with two parents, and handle
--- a/hgext/convert/darcs.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/convert/darcs.py Sat Jun 28 09:28:01 2008 +0200
@@ -110,9 +110,8 @@
copies[elt.get('from')] = elt.get('to')
else:
changes.append((elt.text.strip(), rev))
- changes.sort()
self.lastrev = rev
- return changes, copies
+ return util.sort(changes), copies
def getfile(self, name, rev):
if rev != self.lastrev:
--- a/hgext/convert/gnuarch.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/convert/gnuarch.py Sat Jun 28 09:28:01 2008 +0200
@@ -130,10 +130,8 @@
for c in cps:
copies[c] = cps[c]
- changes.sort()
self.lastrev = rev
-
- return changes, copies
+ return util.sort(changes), copies
def getcommit(self, rev):
changes = self.changes[rev]
--- a/hgext/convert/hg.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/convert/hg.py Sat Jun 28 09:28:01 2008 +0200
@@ -157,21 +157,18 @@
def puttags(self, tags):
try:
- parentctx = self.repo.changectx(self.tagsbranch)
+ parentctx = self.repo[self.tagsbranch]
tagparent = parentctx.node()
except RepoError, inst:
parentctx = None
tagparent = nullid
try:
- old = parentctx.filectx(".hgtags").data()
- oldlines = old.splitlines(1)
- oldlines.sort()
+ oldlines = util.sort(parentctx['.hgtags'].data().splitlines(1))
except:
oldlines = []
- newlines = [("%s %s\n" % (tags[tag], tag)) for tag in tags.keys()]
- newlines.sort()
+ newlines = util.sort([("%s %s\n" % (tags[tag], tag)) for tag in tags])
if newlines == oldlines:
return None
@@ -212,25 +209,24 @@
def changectx(self, rev):
if self.lastrev != rev:
- self.lastctx = self.repo.changectx(rev)
+ self.lastctx = self.repo[rev]
self.lastrev = rev
return self.lastctx
def getheads(self):
if self.rev:
- return [hex(self.repo.changectx(self.rev).node())]
+ return [hex(self.repo[self.rev].node())]
else:
return [hex(node) for node in self.repo.heads()]
def getfile(self, name, rev):
try:
- return self.changectx(rev).filectx(name).data()
+ return self.changectx(rev)[name].data()
except revlog.LookupError, err:
raise IOError(err)
def getmode(self, name, rev):
- m = self.changectx(rev).manifest()
- return (m.execf(name) and 'x' or '') + (m.linkf(name) and 'l' or '')
+ return self.changectx(rev).manifest().flags(name)
def getchanges(self, rev):
ctx = self.changectx(rev)
@@ -239,8 +235,7 @@
else:
m, a, r = self.repo.status(ctx.parents()[0].node(), ctx.node())[:3]
changes = [(name, rev) for name in m + a + r]
- changes.sort()
- return (changes, self.getcopies(ctx, m + a))
+ return util.sort(changes), self.getcopies(ctx, m + a)
def getcopies(self, ctx, files):
copies = {}
--- a/hgext/convert/subversion.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/convert/subversion.py Sat Jun 28 09:28:01 2008 +0200
@@ -658,8 +658,7 @@
# This will fail if a directory was copied
# from another branch and then some of its files
# were deleted in the same transaction.
- children = self._find_children(path, revnum)
- children.sort()
+ children = util.sort(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
@@ -732,8 +731,7 @@
parents = []
# check whether this revision is the start of a branch or part
# of a branch renaming
- orig_paths = orig_paths.items()
- orig_paths.sort()
+ orig_paths = util.sort(orig_paths.items())
root_paths = [(p,e) for p,e in orig_paths if self.module.startswith(p)]
if root_paths:
path, ent = root_paths[-1]
@@ -1045,10 +1043,9 @@
return dirs
def add_dirs(self, files):
- add_dirs = [d for d in self.dirs_of(files)
+ add_dirs = [d for d in util.sort(self.dirs_of(files))
if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
if add_dirs:
- add_dirs.sort()
self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
return add_dirs
@@ -1058,8 +1055,7 @@
return files
def tidy_dirs(self, names):
- dirs = list(self.dirs_of(names))
- dirs.sort()
+ dirs = util.sort(self.dirs_of(names))
dirs.reverse()
deleted = []
for d in dirs:
--- a/hgext/extdiff.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/extdiff.py Sat Jun 28 09:28:01 2008 +0200
@@ -52,7 +52,6 @@
def snapshot_node(ui, repo, files, node, tmproot):
'''snapshot files as of some revision'''
- mf = repo.changectx(node).manifest()
dirname = os.path.basename(repo.root)
if dirname == "":
dirname = "root"
@@ -61,17 +60,18 @@
os.mkdir(base)
ui.note(_('making snapshot of %d files from rev %s\n') %
(len(files), short(node)))
+ ctx = repo[node]
for fn in files:
- if not fn in mf:
+ wfn = util.pconvert(fn)
+ if not wfn in ctx:
# skipping new file after a merge ?
continue
- wfn = util.pconvert(fn)
ui.note(' %s\n' % wfn)
dest = os.path.join(base, wfn)
destdir = os.path.dirname(dest)
if not os.path.isdir(destdir):
os.makedirs(destdir)
- data = repo.wwritedata(wfn, repo.file(wfn).read(mf[wfn]))
+ data = repo.wwritedata(wfn, ctx[wfn].data())
open(dest, 'wb').write(data)
return dirname
@@ -122,8 +122,7 @@
'''
node1, node2 = cmdutil.revpair(repo, opts['rev'])
matcher = cmdutil.match(repo, pats, opts)
- modified, added, removed, deleted, unknown = repo.status(
- node1, node2, matcher)[:5]
+ modified, added, removed = repo.status(node1, node2, matcher)[:3]
if not (modified or added or removed):
return 0
--- a/hgext/gpg.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/gpg.py Sat Jun 28 09:28:01 2008 +0200
@@ -239,7 +239,7 @@
repo.opener("localsigs", "ab").write(sigmessage)
return
- for x in repo.status()[:5]:
+ for x in repo.status(unknown=True)[:5]:
if ".hgsigs" in x and not opts["force"]:
raise util.Abort(_("working copy of .hgsigs is changed "
"(please commit .hgsigs manually "
--- a/hgext/graphlog.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/graphlog.py Sat Jun 28 09:28:01 2008 +0200
@@ -13,6 +13,7 @@
from mercurial.i18n import _
from mercurial.node import nullrev
from mercurial.util import Abort, canonpath
+from mercurial import util
def revision_grapher(repo, start_rev, stop_rev):
"""incremental revision grapher
@@ -53,8 +54,7 @@
for parent in parents:
if parent not in next_revs:
parents_to_add.append(parent)
- parents_to_add.sort()
- next_revs[rev_index:rev_index + 1] = parents_to_add
+ next_revs[rev_index:rev_index + 1] = util.sort(parents_to_add)
edges = []
for parent in parents:
@@ -89,7 +89,7 @@
assert start_rev >= stop_rev
curr_rev = start_rev
revs = []
- filerev = repo.file(path).count() - 1
+ filerev = len(repo.file(path)) - 1
while filerev >= 0:
fctx = repo.filectx(path, fileid=filerev)
@@ -105,8 +105,7 @@
for parent in parents:
if parent not in next_revs:
parents_to_add.append(parent)
- parents_to_add.sort()
- next_revs[rev_index:rev_index + 1] = parents_to_add
+ next_revs[rev_index:rev_index + 1] = util.sort(parents_to_add)
edges = []
for parent in parents:
@@ -198,7 +197,7 @@
revs = revrange(repo, rev_opt)
return (max(revs), min(revs))
else:
- return (repo.changelog.count() - 1, 0)
+ return (len(repo) - 1, 0)
def graphlog(ui, repo, path=None, **opts):
"""show revision history alongside an ASCII revision graph
--- a/hgext/hgk.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/hgk.py Sat Jun 28 09:28:01 2008 +0200
@@ -52,12 +52,10 @@
"""diff trees from two commits"""
def __difftree(repo, node1, node2, files=[]):
assert node2 is not None
- mmap = repo.changectx(node1).manifest()
- mmap2 = repo.changectx(node2).manifest()
+ mmap = repo[node1].manifest()
+ mmap2 = repo[node2].manifest()
m = cmdutil.match(repo, files)
- status = repo.status(node1, node2, match=m)[:5]
- modified, added, removed, deleted, unknown = status
-
+ modified, added, removed = repo.status(node1, node2, m)[:3]
empty = short(nullid)
for f in modified:
@@ -103,7 +101,7 @@
def catcommit(ui, repo, n, prefix, ctx=None):
nlprefix = '\n' + prefix;
if ctx is None:
- ctx = repo.changectx(n)
+ ctx = repo[n]
(p1, p2) = ctx.parents()
ui.write("tree %s\n" % short(ctx.changeset()[0])) # use ctx.node() instead ??
if p1: ui.write("parent %s\n" % short(p1.node()))
@@ -175,7 +173,7 @@
# you can specify a commit to stop at by starting the sha1 with ^
def revtree(ui, args, repo, full="tree", maxnr=0, parents=False):
def chlogwalk():
- count = repo.changelog.count()
+ count = len(repo)
i = count
l = [0] * 100
chunk = 100
@@ -191,7 +189,7 @@
l[chunk - x:] = [0] * (chunk - x)
break
if full != None:
- l[x] = repo.changectx(i + x)
+ l[x] = repo[i + x]
l[x].changeset() # force reading
else:
l[x] = 1
--- a/hgext/inotify/__init__.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/inotify/__init__.py Sat Jun 28 09:28:01 2008 +0200
@@ -47,13 +47,12 @@
# to recurse.
inotifyserver = False
- def status(self, match, list_ignored, list_clean,
- list_unknown=True):
+ def status(self, match, ignored, clean, unknown=True):
files = match.files()
try:
- if not list_ignored and not self.inotifyserver:
+ if not ignored and not self.inotifyserver:
result = client.query(ui, repo, files, match, False,
- list_clean, list_unknown)
+ clean, unknown)
if result is not None:
return result
except socket.error, err:
@@ -82,15 +81,14 @@
if query:
try:
return query(ui, repo, files or [], match,
- list_ignored, list_clean, list_unknown)
+ ignored, clean, unknown)
except socket.error, err:
ui.warn(_('could not talk to new inotify '
'server: %s\n') % err[1])
ui.print_exc()
return super(inotifydirstate, self).status(
- match, list_ignored, list_clean,
- list_unknown)
+ match, ignored, clean, unknown)
repo.dirstate.__class__ = inotifydirstate
--- a/hgext/inotify/client.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/inotify/client.py Sat Jun 28 09:28:01 2008 +0200
@@ -11,7 +11,7 @@
import common
import os, select, socket, stat, struct, sys
-def query(ui, repo, names, match, list_ignored, list_clean, list_unknown=True):
+def query(ui, repo, names, match, ignored, clean, unknown=True):
sock = socket.socket(socket.AF_UNIX)
sockpath = repo.join('inotify.sock')
sock.connect(sockpath)
@@ -20,10 +20,10 @@
for n in names or []:
yield n
states = 'almrx!'
- if list_ignored:
+ if ignored:
raise ValueError('this is insanity')
- if list_clean: states += 'n'
- if list_unknown: states += '?'
+ if clean: states += 'n'
+ if unknown: states += '?'
yield states
req = '\0'.join(genquery())
--- a/hgext/inotify/server.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/inotify/server.py Sat Jun 28 09:28:01 2008 +0200
@@ -534,9 +534,7 @@
self.ui.note('%s processing %d deferred events as %d\n' %
(self.event_time(), self.deferred,
len(self.eventq)))
- eventq = self.eventq.items()
- eventq.sort()
- for wpath, evts in eventq:
+ for wpath, evts in util.sort(self.eventq.items()):
for evt in evts:
self.deferred_event(wpath, evt)
self.eventq.clear()
--- a/hgext/keyword.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/keyword.py Sat Jun 28 09:28:01 2008 +0200
@@ -78,7 +78,7 @@
"Log = {desc}" expands to the first line of the changeset description.
'''
-from mercurial import commands, cmdutil, context, dispatch, filelog, revlog
+from mercurial import commands, cmdutil, dispatch, filelog, revlog
from mercurial import patch, localrepo, templater, templatefilters, util
from mercurial.hgweb import webcommands
from mercurial.node import nullid, hex
@@ -142,7 +142,7 @@
def getnode(self, path, fnode):
'''Derives changenode from file path and filenode.'''
# used by kwfilelog.read and kwexpand
- c = context.filectx(self.repo, path, fileid=fnode)
+ c = self.repo.filectx(path, fileid=fnode)
return c.node()
def substitute(self, data, path, node, subfunc):
@@ -163,25 +163,26 @@
return self.substitute(data, path, changenode, self.re_kw.sub)
return data
- def iskwfile(self, path, islink):
+ def iskwfile(self, path, flagfunc):
'''Returns true if path matches [keyword] pattern
and is not a symbolic link.
Caveat: localrepository._link fails on Windows.'''
- return self.matcher(path) and not islink(path)
+ return self.matcher(path) and not 'l' in flagfunc(path)
def overwrite(self, node, expand, files):
'''Overwrites selected files expanding/shrinking keywords.'''
- ctx = self.repo.changectx(node)
- mf = ctx.manifest()
if node is not None: # commit
+ ctx = self.repo[node]
+ mf = ctx.manifest()
files = [f for f in ctx.files() if f in mf]
notify = self.ui.debug
else: # kwexpand/kwshrink
+ ctx = self.repo['.']
+ mf = ctx.manifest()
notify = self.ui.note
- candidates = [f for f in files if self.iskwfile(f, mf.linkf)]
+ candidates = [f for f in files if self.iskwfile(f, ctx.flags)]
if candidates:
self.restrict = True # do not expand when reading
- candidates.sort()
action = expand and 'expanding' or 'shrinking'
for f in candidates:
fp = self.repo.file(f)
@@ -251,12 +252,12 @@
return t2 != text
return revlog.revlog.cmp(self, node, text)
-def _status(ui, repo, kwt, *pats, **opts):
+def _status(ui, repo, kwt, unknown, *pats, **opts):
'''Bails out if [keyword] configuration is not active.
Returns status of working directory.'''
if kwt:
matcher = cmdutil.match(repo, pats, opts)
- return repo.status(match=matcher, list_clean=True)
+ return repo.status(match=matcher, unknown=unknown, clean=True)
if ui.configitems('keyword'):
raise util.Abort(_('[keyword] patterns cannot match'))
raise util.Abort(_('no [keyword] patterns configured'))
@@ -266,15 +267,15 @@
if repo.dirstate.parents()[1] != nullid:
raise util.Abort(_('outstanding uncommitted merge'))
kwt = kwtools['templater']
- status = _status(ui, repo, kwt, *pats, **opts)
- modified, added, removed, deleted, unknown, ignored, clean = status
+ status = _status(ui, repo, kwt, False, *pats, **opts)
+ modified, added, removed, deleted = status[:4]
if modified or added or removed or deleted:
raise util.Abort(_('outstanding uncommitted changes'))
wlock = lock = None
try:
wlock = repo.wlock()
lock = repo.lock()
- kwt.overwrite(None, expand, clean)
+ kwt.overwrite(None, expand, status[6])
finally:
del wlock, lock
@@ -378,15 +379,11 @@
That is, files matched by [keyword] config patterns but not symlinks.
'''
kwt = kwtools['templater']
- status = _status(ui, repo, kwt, *pats, **opts)
+ status = _status(ui, repo, kwt, opts.get('untracked'), *pats, **opts)
modified, added, removed, deleted, unknown, ignored, clean = status
- files = modified + added + clean
- if opts.get('untracked'):
- files += unknown
- files.sort()
- wctx = repo.workingctx()
- islink = lambda p: 'l' in wctx.fileflags(p)
- kwfiles = [f for f in files if kwt.iskwfile(f, islink)]
+ files = util.sort(modified + added + clean + unknown)
+ wctx = repo[None]
+ kwfiles = [f for f in files if kwt.iskwfile(f, wctx.flags)]
cwd = pats and repo.getcwd() or ''
kwfstats = not opts.get('ignore') and (('K', kwfiles),) or ()
if opts.get('all') or opts.get('ignore'):
@@ -511,7 +508,7 @@
comparing against working dir.'''
if node2 is not None:
kwt.matcher = util.never
- elif node1 is not None and node1 != repo.changectx().node():
+ elif node1 is not None and node1 != repo['.'].node():
kwt.restrict = True
patch_diff(repo, node1, node2, match, fp, changes, opts)
--- a/hgext/mq.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/mq.py Sat Jun 28 09:28:01 2008 +0200
@@ -143,8 +143,7 @@
bad = self.check_guard(guard)
if bad:
raise util.Abort(bad)
- guards = dict.fromkeys(guards).keys()
- guards.sort()
+ guards = util.sort(util.unique(guards))
self.ui.debug('active guards: %s\n' % ' '.join(guards))
self.active_guards = guards
self.guards_dirty = True
@@ -342,7 +341,7 @@
hg.clean(repo, head)
self.strip(repo, n, update=False, backup='strip')
- ctx = repo.changectx(rev)
+ ctx = repo[rev]
ret = hg.merge(repo, rev)
if ret:
raise util.Abort(_("update returned %d") % ret)
@@ -536,8 +535,7 @@
return (err, n)
def _clean_series(self, patches):
- indices = [self.find_series(p) for p in patches]
- indices.sort()
+ indices = util.sort([self.find_series(p) for p in patches])
for i in indices[-1::-1]:
del self.full_series[i]
self.parse_series()
@@ -545,10 +543,10 @@
def finish(self, repo, revs):
revs.sort()
- firstrev = repo.changelog.rev(revlog.bin(self.applied[0].rev))
+ firstrev = repo[self.applied[0].rev].rev()
appliedbase = 0
patches = []
- for rev in revs:
+ for rev in util.sort(revs):
if rev < firstrev:
raise util.Abort(_('revision %d is not managed') % rev)
base = revlog.bin(self.applied[appliedbase].rev)
@@ -852,7 +850,7 @@
self.ui.warn(_('cleaning up working directory...'))
node = repo.dirstate.parents()[0]
hg.revert(repo, node, None)
- unknown = repo.status()[4]
+ unknown = repo.status(unknown=True)[4]
# only remove unknown files that we know we touched or
# created while patching
for f in unknown:
@@ -933,7 +931,7 @@
qp = self.qparents(repo, rev)
changes = repo.changelog.read(qp)
mmap = repo.manifest.read(changes[0])
- m, a, r, d, u = repo.status(qp, top)[:5]
+ m, a, r, d = repo.status(qp, top)[:4]
if d:
raise util.Abort("deletions found between repo revs")
for f in m:
@@ -1066,11 +1064,11 @@
# patch already
#
# this should really read:
- # mm, dd, aa, aa2, uu = repo.status(tip, patchparent)[:5]
+ # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
# but we do it backwards to take advantage of manifest/chlog
# caching against the next repo.status call
#
- mm, aa, dd, aa2, uu = repo.status(patchparent, tip)[:5]
+ mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
changes = repo.changelog.read(tip)
man = repo.manifest.read(changes[0])
aaa = aa[:]
@@ -1078,7 +1076,7 @@
match = cmdutil.matchfiles(repo, mm + aa + dd)
else:
match = cmdutil.matchall(repo)
- m, a, r, d, u = repo.status(match=match)[:5]
+ m, a, r, d = repo.status(match=match)[:4]
# we might end up with files that were added between
# tip and the dirstate parent, but then changed in the
@@ -1111,7 +1109,7 @@
m = util.unique(mm)
r = util.unique(dd)
a = util.unique(aa)
- c = [filter(matchfn, l) for l in (m, a, r, [], u)]
+ c = [filter(matchfn, l) for l in (m, a, r)]
match = cmdutil.matchfiles(repo, util.unique(c[0] + c[1] + c[2]))
patch.diff(repo, patchparent, match=match,
fp=patchf, changes=c, opts=self.diffopts())
@@ -1261,8 +1259,7 @@
self.guards_path)
and not fl.startswith('.')):
msng_list.append(fl)
- msng_list.sort()
- for x in msng_list:
+ for x in util.sort(msng_list):
pfx = self.ui.verbose and ('D ') or ''
self.ui.write("%s%s\n" % (pfx, displayname(x)))
@@ -2319,7 +2316,7 @@
# we might as well use it, but we won't save it.
# update the cache up to the tip
- self._updatebranchcache(partial, start, cl.count())
+ self._updatebranchcache(partial, start, len(cl))
return partial
--- a/hgext/notify.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/notify.py Sat Jun 28 09:28:01 2008 +0200
@@ -156,9 +156,7 @@
if fnmatch.fnmatch(self.repo.root, pat):
for user in users.split(','):
subs[self.fixmail(user)] = 1
- subs = subs.keys()
- subs.sort()
- return subs
+ return util.sort(subs)
def url(self, path=None):
return self.ui.config('web', 'baseurl') + (path or self.root)
@@ -269,11 +267,11 @@
node = bin(node)
ui.pushbuffer()
if hooktype == 'changegroup':
- start = repo.changelog.rev(node)
- end = repo.changelog.count()
+ start = repo[node].rev()
+ end = len(repo)
count = end - start
for rev in xrange(start, end):
- n.node(repo.changelog.node(rev))
+ n.node(repo[node].rev())
n.diff(node, repo.changelog.tip())
else:
count = 1
--- a/hgext/purge.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/purge.py Sat Jun 28 09:28:01 2008 +0200
@@ -56,79 +56,42 @@
files that this program would delete use the --print option.
'''
act = not opts['print']
- ignored = bool(opts['all'])
- abort_on_err = bool(opts['abort_on_err'])
- eol = opts['print0'] and '\0' or '\n'
- if eol == '\0':
- # --print0 implies --print
- act = False
- force = bool(opts['force'])
-
- def error(msg):
- if abort_on_err:
- raise util.Abort(msg)
- else:
- ui.warn(_('warning: %s\n') % msg)
+ eol = '\n'
+ if opts['print0']:
+ eol = '\0'
+ act = False # --print0 implies --print
def remove(remove_func, name):
if act:
try:
remove_func(os.path.join(repo.root, name))
except OSError, e:
- error(_('%s cannot be removed') % name)
+ m = _('%s cannot be removed') % name
+ if opts['abort_on_err']:
+ raise util.Abort(m)
+ ui.warn(_('warning: %s\n') % m)
else:
ui.write('%s%s' % (name, eol))
- if not force:
- _check_fs(ui, repo)
-
directories = []
- files = []
match = cmdutil.match(repo, dirs, opts)
match.dir = directories.append
- for src, f, st in repo.dirstate.statwalk(match, ignored=ignored):
- if src == 'f' and f not in repo.dirstate:
- files.append(f)
-
- directories.sort()
+ status = repo.status(match=match, ignored=opts['all'], unknown=True)
- for f in files:
- if f not in repo.dirstate:
- ui.note(_('Removing file %s\n') % f)
- remove(os.remove, f)
+ for f in util.sort(status[4] + status[5]):
+ ui.note(_('Removing file %s\n') % f)
+ remove(os.remove, f)
- for f in directories[::-1]:
+ for f in util.sort(directories)[::-1]:
if match(f) and not os.listdir(repo.wjoin(f)):
ui.note(_('Removing directory %s\n') % f)
remove(os.rmdir, f)
-def _check_fs(ui, repo):
- """Abort if there is the chance of having problems with name-mangling fs
-
- In a name mangling filesystem (e.g. a case insensitive one)
- dirstate.walk() can yield filenames different from the ones
- stored in the dirstate. This already confuses the status and
- add commands, but with purge this may cause data loss.
-
- To prevent this, this function will abort if there are uncommitted
- changes.
- """
-
- # We can't use (files, match) to do a partial walk here - we wouldn't
- # notice a modified README file if the user ran "hg purge readme"
- modified, added, removed, deleted = repo.status()[:4]
- if modified or added or removed or deleted:
- if not util.checkfolding(repo.path) and not ui.quiet:
- ui.warn(_("Purging on name mangling filesystems is not "
- "fully supported.\n"))
- raise util.Abort(_("outstanding uncommitted changes"))
-
cmdtable = {
'purge|clean':
(purge,
[('a', 'abort-on-err', None, _('abort if an error occurs')),
('', 'all', None, _('purge ignored files too')),
- ('f', 'force', None, _('purge even when there are uncommitted changes')),
('p', 'print', None, _('print the file names instead of deleting them')),
('0', 'print0', None, _('end filenames with NUL, for use with xargs'
' (implies -p)')),
--- a/hgext/record.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/record.py Sat Jun 28 09:28:01 2008 +0200
@@ -405,8 +405,8 @@
if match.files():
changes = None
else:
- changes = repo.status(match=match)[:5]
- modified, added, removed = changes[:3]
+ changes = repo.status(match=match)[:3]
+ modified, added, removed = changes
match = cmdutil.matchfiles(repo, modified + added + removed)
diffopts = mdiff.diffopts(git=True, nodates=True)
fp = cStringIO.StringIO()
@@ -431,7 +431,7 @@
if changes is None:
match = cmdutil.matchfiles(repo, newfiles)
- changes = repo.status(match=match)[:5]
+ changes = repo.status(match=match)
modified = dict.fromkeys(changes[0])
# 2. backup changed files, so we can restore them in the end
--- a/hgext/transplant.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/transplant.py Sat Jun 28 09:28:01 2008 +0200
@@ -88,9 +88,7 @@
def apply(self, repo, source, revmap, merges, opts={}):
'''apply the revisions in revmap one by one in revision order'''
- revs = revmap.keys()
- revs.sort()
-
+ revs = util.sort(revmap)
p1, p2 = repo.dirstate.parents()
pulls = []
diffopts = patch.diffopts(self.ui, opts)
@@ -310,9 +308,7 @@
if not os.path.isdir(self.path):
os.mkdir(self.path)
series = self.opener('series', 'w')
- revs = revmap.keys()
- revs.sort()
- for rev in revs:
+ for rev in util.sort(revmap):
series.write(revlog.hex(revmap[rev]) + '\n')
if merges:
series.write('# Merges\n')
@@ -572,10 +568,6 @@
for r in merges:
revmap[source.changelog.rev(r)] = r
- revs = revmap.keys()
- revs.sort()
- pulls = []
-
tp.apply(repo, source, revmap, merges, opts)
finally:
if bundle:
--- a/hgext/win32text.py Thu Jun 26 13:37:47 2008 -0700
+++ b/hgext/win32text.py Sat Jun 28 09:28:01 2008 +0200
@@ -98,8 +98,8 @@
def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
halt = False
- for rev in xrange(repo.changelog.rev(bin(node)), repo.changelog.count()):
- c = repo.changectx(rev)
+ for rev in xrange(repo[node].rev(), len(repo)):
+ c = repo[rev]
for f in c.files():
if f not in c:
continue
--- a/mercurial/archival.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/archival.py Sat Jun 28 09:28:01 2008 +0200
@@ -208,18 +208,17 @@
data = repo.wwritedata(name, data)
archiver.addfile(name, mode, islink, data)
- ctx = repo.changectx(node)
if kind not in archivers:
raise util.Abort(_("unknown archive type '%s'" % kind))
+
+ ctx = repo[node]
archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0])
- m = ctx.manifest()
- items = m.items()
- items.sort()
+
if repo.ui.configbool("ui", "archivemeta", True):
write('.hg_archival.txt', 0644, False,
lambda: 'repo: %s\nnode: %s\n' % (
hex(repo.changelog.node(0)), hex(node)))
- for filename, filenode in items:
- write(filename, m.execf(filename) and 0755 or 0644, m.linkf(filename),
- lambda: repo.file(filename).read(filenode))
+ for f in ctx:
+ ff = ctx.flags(f)
+ write(f, 'x' in ff and 0755 or 0644, 'l' in ff, ctx[f].data)
archiver.done()
--- a/mercurial/bundlerepo.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/bundlerepo.py Sat Jun 28 09:28:01 2008 +0200
@@ -34,7 +34,7 @@
for chunk in changegroup.chunkiter(bundlefile):
pos = bundlefile.tell()
yield chunk, pos - len(chunk)
- n = self.count()
+ n = len(self)
prev = None
for chunk, start in chunkpositer():
size = len(chunk)
--- a/mercurial/changelog.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/changelog.py Sat Jun 28 09:28:01 2008 +0200
@@ -82,7 +82,7 @@
"delay visibility of index updates to other readers"
self._realopener = self.opener
self.opener = self._delayopener
- self._delaycount = self.count()
+ self._delaycount = len(self)
self._delaybuf = []
self._delayname = None
@@ -108,7 +108,7 @@
# if we're doing an initial clone, divert to another file
if self._delaycount == 0:
self._delayname = fp.name
- if not self.count():
+ if not len(self):
# make sure to truncate the file
mode = mode.replace('a', 'w')
return self._realopener(name + ".a", mode)
@@ -130,9 +130,7 @@
def encode_extra(self, d):
# keys must be sorted to produce a deterministic changelog entry
- keys = d.keys()
- keys.sort()
- items = [_string_escape('%s:%s' % (k, d[k])) for k in keys]
+ items = [_string_escape('%s:%s' % (k, d[k])) for k in util.sort(d)]
return "\0".join(items)
def read(self, node):
@@ -175,7 +173,7 @@
files = l[3:]
return (manifest, user, (time, timezone), files, desc, extra)
- def add(self, manifest, list, desc, transaction, p1=None, p2=None,
+ def add(self, manifest, files, desc, transaction, p1=None, p2=None,
user=None, date=None, extra={}):
user, desc = util.fromlocal(user), util.fromlocal(desc)
@@ -189,7 +187,6 @@
if extra:
extra = self.encode_extra(extra)
parseddate = "%s %s" % (parseddate, extra)
- list.sort()
- l = [hex(manifest), user, parseddate] + list + ["", desc]
+ l = [hex(manifest), user, parseddate] + util.sort(files) + ["", desc]
text = "\n".join(l)
- return self.addrevision(text, transaction, self.count(), p1, p2)
+ return self.addrevision(text, transaction, len(self), p1, p2)
--- a/mercurial/cmdutil.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/cmdutil.py Sat Jun 28 09:28:01 2008 +0200
@@ -126,7 +126,7 @@
if revrangesep in revs[0]:
start, end = revs[0].split(revrangesep, 1)
start = revfix(repo, start, 0)
- end = revfix(repo, end, repo.changelog.count() - 1)
+ end = revfix(repo, end, len(repo) - 1)
else:
start = revfix(repo, revs[0], None)
elif len(revs) == 2:
@@ -151,7 +151,7 @@
if revrangesep in spec:
start, end = spec.split(revrangesep, 1)
start = revfix(repo, start, 0)
- end = revfix(repo, end, repo.changelog.count() - 1)
+ end = revfix(repo, end, len(repo) - 1)
step = start > end and -1 or 1
for rev in xrange(start, end+step, step):
if rev in seen:
@@ -245,7 +245,7 @@
'''find renamed files -- yields (before, after, score) tuples'''
if added is None or removed is None:
added, removed = repo.status()[1:3]
- ctx = repo.changectx()
+ ctx = repo['.']
for a in added:
aa = repo.wread(a)
bestname, bestscore = None, threshold
@@ -653,9 +653,7 @@
self.ui.write(_("copies: %s\n") % ' '.join(copies))
if extra and self.ui.debugflag:
- extraitems = extra.items()
- extraitems.sort()
- for key, value in extraitems:
+ for key, value in util.sort(extra.items()):
self.ui.write(_("extra: %s=%s\n")
% (key, value.encode('string_escape')))
@@ -799,9 +797,7 @@
return showlist('tag', self.repo.nodetags(changenode), **args)
def showextras(**args):
- extras = changes[5].items()
- extras.sort()
- for key, value in extras:
+ for key, value in util.sort(changes[5].items()):
args = args.copy()
args.update(dict(key=key, value=value))
yield self.t('extra', **args)
@@ -930,7 +926,7 @@
def finddate(ui, repo, date):
"""Find the tipmost changeset that matches the given date spec"""
df = util.matchdate(date)
- get = util.cachefunc(lambda r: repo.changectx(r).changeset())
+ get = util.cachefunc(lambda r: repo[r].changeset())
changeiter, matchfn = walkchangerevs(ui, repo, [], get, {'rev':None})
results = {}
for st, rev, fns in changeiter:
@@ -988,11 +984,11 @@
m = match(repo, pats, opts)
follow = opts.get('follow') or opts.get('follow_first')
- if repo.changelog.count() == 0:
+ if not len(repo):
return [], m
if follow:
- defrange = '%s:0' % repo.changectx().rev()
+ defrange = '%s:0' % repo['.'].rev()
else:
defrange = '-1:0'
revs = revrange(repo, opts['rev'] or [defrange])
@@ -1007,9 +1003,9 @@
if not slowpath:
# Only files, no patterns. Check the history of each file.
def filerevgen(filelog, node):
- cl_count = repo.changelog.count()
+ cl_count = len(repo)
if node is None:
- last = filelog.count() - 1
+ last = len(filelog) - 1
else:
last = filelog.rev(node)
for i, window in increasing_windows(last, nullrev):
@@ -1032,7 +1028,7 @@
minrev, maxrev = min(revs), max(revs)
for file_, node in iterfiles():
filelog = repo.file(file_)
- if filelog.count() == 0:
+ if not len(filelog):
if node is None:
# A zero count may be a directory or deleted file, so
# try to find matching entries on the slow path.
@@ -1058,8 +1054,7 @@
# The slow path checks files modified in every changeset.
def changerevgen():
- for i, window in increasing_windows(repo.changelog.count()-1,
- nullrev):
+ for i, window in increasing_windows(len(repo) - 1, nullrev):
for j in xrange(i - window, i + 1):
yield j, change(j)[3]
@@ -1130,9 +1125,7 @@
for i, window in increasing_windows(0, len(revs)):
yield 'window', revs[0] < revs[-1], revs[-1]
nrevs = [rev for rev in revs[i:i+window] if want(rev)]
- srevs = list(nrevs)
- srevs.sort()
- for rev in srevs:
+ for rev in util.sort(list(nrevs)):
fns = fncache.get(rev)
if not fns:
def fns_generator():
@@ -1159,9 +1152,8 @@
m = match(repo, pats, opts)
if pats:
- status = repo.status(match=m)
- modified, added, removed, deleted, unknown = status[:5]
- files = modified + added + removed
+ modified, added, removed = repo.status(match=m)[:3]
+ files = util.sort(modified + added + removed)
slist = None
for f in m.files():
if f == '.':
@@ -1175,11 +1167,8 @@
raise util.Abort(_("file %s not found!") % rel)
if stat.S_ISDIR(mode):
name = f + '/'
- if slist is None:
- slist = list(files)
- slist.sort()
- i = bisect.bisect(slist, name)
- if i >= len(slist) or not slist[i].startswith(name):
+ i = bisect.bisect(files, name)
+ if i >= len(files) or not files[i].startswith(name):
raise util.Abort(_("no match under directory %s!")
% rel)
elif not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)):
--- a/mercurial/commands.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/commands.py Sat Jun 28 09:28:01 2008 +0200
@@ -107,7 +107,7 @@
lastfunc = funcmap[-1]
funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
- ctx = repo.changectx(opts['rev'])
+ ctx = repo[opts['rev']]
m = cmdutil.match(repo, pats, opts)
for abs in repo.walk(m, ctx.node()):
@@ -154,7 +154,7 @@
The default is the basename of the archive, with suffixes removed.
'''
- ctx = repo.changectx(opts['rev'])
+ ctx = repo[opts['rev']]
if not ctx:
raise util.Abort(_('repository has no revisions'))
node = ctx.node()
@@ -189,7 +189,7 @@
hand. The result of this merge is not committed, as for a normal
merge.
- See 'hg help dates' for a list of formats valid for -d/--date.
+ See \'hg help dates\' for a list of formats valid for -d/--date.
'''
if rev and node:
raise util.Abort(_("please specify just one revision"))
@@ -359,7 +359,7 @@
if label:
if not opts.get('force') and label in repo.branchtags():
- if label not in [p.branch() for p in repo.workingctx().parents()]:
+ if label not in [p.branch() for p in repo.parents()]:
raise util.Abort(_('a branch of the same name already exists'
' (use --force to override)'))
repo.dirstate.setbranch(util.fromlocal(label))
@@ -378,11 +378,10 @@
Use the command 'hg update' to switch to an existing branch.
"""
hexfunc = ui.debugflag and hex or short
- activebranches = [util.tolocal(repo.changectx(n).branch())
+ activebranches = [util.tolocal(repo[n].branch())
for n in repo.heads()]
- branches = [(tag in activebranches, repo.changelog.rev(node), tag)
- for tag, node in repo.branchtags().items()]
- branches.sort()
+ branches = util.sort([(tag in activebranches, repo.changelog.rev(node), tag)
+ for tag, node in repo.branchtags().items()])
branches.reverse()
for isactive, node, tag in branches:
@@ -483,7 +482,7 @@
%d dirname of file being printed, or '.' if in repo root
%p root-relative path name of file being printed
"""
- ctx = repo.changectx(opts['rev'])
+ ctx = repo[opts['rev']]
err = 1
m = cmdutil.match(repo, (file1,) + pats, opts)
for abs in repo.walk(m, ctx.node()):
@@ -635,35 +634,30 @@
ui.write("%s\n" % "\n".join(options))
return
- clist = cmdutil.findpossible(ui, cmd, table).keys()
- clist.sort()
- ui.write("%s\n" % "\n".join(clist))
+ ui.write("%s\n" % "\n".join(util.sort(cmdutil.findpossible(ui, cmd, table))))
def debugfsinfo(ui, path = "."):
file('.debugfsinfo', 'w').write('')
ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
- ui.write('case-sensitive: %s\n' % (util.checkfolding('.debugfsinfo')
+ ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
and 'yes' or 'no'))
os.unlink('.debugfsinfo')
-def debugrebuildstate(ui, repo, rev=""):
+def debugrebuildstate(ui, repo, rev="tip"):
"""rebuild the dirstate as it would look like for the given revision"""
- if rev == "":
- rev = repo.changelog.tip()
- ctx = repo.changectx(rev)
- files = ctx.manifest()
+ ctx = repo[rev]
wlock = repo.wlock()
try:
- repo.dirstate.rebuild(rev, files)
+ repo.dirstate.rebuild(ctx.node(), ctx.manifest())
finally:
del wlock
def debugcheckstate(ui, repo):
"""validate the correctness of the current dirstate"""
parent1, parent2 = repo.dirstate.parents()
- m1 = repo.changectx(parent1).manifest()
- m2 = repo.changectx(parent2).manifest()
+ m1 = repo[parent1].manifest()
+ m2 = repo[parent2].manifest()
errors = 0
for f in repo.dirstate:
state = repo.dirstate[f]
@@ -730,11 +724,9 @@
def debugstate(ui, repo, nodates=None):
"""show the contents of the current dirstate"""
- k = repo.dirstate._map.items()
- k.sort()
timestr = ""
showdate = not nodates
- for file_, ent in k:
+ for file_, ent in util.sort(repo.dirstate._map.items()):
if showdate:
if ent[3] == -1:
# Pad or slice to locale representation
@@ -776,7 +768,7 @@
r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
ui.write(" rev offset length base linkrev" +
" nodeid p1 p2\n")
- for i in xrange(r.count()):
+ for i in r:
node = r.node(i)
try:
pp = r.parents(node)
@@ -790,7 +782,7 @@
"""dump an index DAG as a .dot file"""
r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
ui.write("digraph G {\n")
- for i in xrange(r.count()):
+ for i in r:
node = r.node(i)
pp = r.parents(node)
ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
@@ -913,7 +905,7 @@
def debugrename(ui, repo, file1, *pats, **opts):
"""dump rename information"""
- ctx = repo.changectx(opts.get('rev', 'tip'))
+ ctx = repo[opts.get('rev')]
m = cmdutil.match(repo, (file1,) + pats, opts)
for abs in repo.walk(m, ctx.node()):
fctx = ctx.filectx(abs)
@@ -1122,7 +1114,7 @@
fstate = {}
skip = {}
- get = util.cachefunc(lambda r: repo.changectx(r).changeset())
+ get = util.cachefunc(lambda r: repo[r].changeset())
changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
found = False
follow = opts.get('follow')
@@ -1130,7 +1122,7 @@
if st == 'window':
matches.clear()
elif st == 'add':
- ctx = repo.changectx(rev)
+ ctx = repo[rev]
matches[rev] = {}
for fn in fns:
if fn in skip:
@@ -1145,9 +1137,7 @@
except revlog.LookupError:
pass
elif st == 'iter':
- states = matches[rev].items()
- states.sort()
- for fn, m in states:
+ for fn, m in util.sort(matches[rev].items()):
copy = copies.get(rev, {}).get(fn)
if fn in skip:
if copy:
@@ -1165,9 +1155,7 @@
fstate[copy] = m
prev[fn] = rev
- fstate = fstate.items()
- fstate.sort()
- for fn, state in fstate:
+ for fn, state in util.sort(fstate.items()):
if fn in skip:
continue
if fn not in copies.get(prev[fn], {}):
@@ -1202,7 +1190,7 @@
heads = []
visitedset = util.set()
for branchrev in branchrevs:
- branch = repo.changectx(branchrev).branch()
+ branch = repo[branchrev].branch()
if branch in visitedset:
continue
visitedset.add(branch)
@@ -1307,8 +1295,7 @@
return
ui.status(header)
- fns = h.keys()
- fns.sort()
+ fns = util.sort(h)
m = max(map(len, fns))
for f in fns:
if ui.verbose:
@@ -1454,7 +1441,7 @@
"can't query remote revision number, branch, or tags")
output = [hexfunc(srepo.lookup(rev))]
elif not rev:
- ctx = repo.workingctx()
+ ctx = repo[None]
parents = ctx.parents()
changed = False
if default or id or num:
@@ -1466,7 +1453,7 @@
output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
(changed) and "+" or ""))
else:
- ctx = repo.changectx(rev)
+ ctx = repo[rev]
if default or id:
output = [hexfunc(ctx.node())]
if num:
@@ -1563,7 +1550,7 @@
message = None
ui.debug(_('message:\n%s\n') % message)
- wp = repo.workingctx().parents()
+ wp = repo.parents()
if opts.get('exact'):
if not nodeid or not p1:
raise util.Abort(_('not a mercurial patch'))
@@ -1756,7 +1743,7 @@
"""
- get = util.cachefunc(lambda r: repo.changectx(r).changeset())
+ get = util.cachefunc(lambda r: repo[r].changeset())
changeiter, matchfn = cmdutil.walkchangerevs(ui, repo, pats, get, opts)
limit = cmdutil.loglimit(opts)
@@ -1765,7 +1752,7 @@
if opts['copies'] and opts['rev']:
endrev = max(cmdutil.revrange(repo, opts['rev'])) + 1
else:
- endrev = repo.changelog.count()
+ endrev = len(repo)
rcache = {}
ncache = {}
def getrenamed(fn, rev):
@@ -1777,7 +1764,7 @@
rcache[fn] = {}
ncache[fn] = {}
fl = repo.file(fn)
- for i in xrange(fl.count()):
+ for i in fl:
node = fl.node(i)
lr = fl.linkrev(node)
renamed = fl.renamed(node)
@@ -1793,7 +1780,7 @@
# filectx logic.
try:
- return repo.changectx(rev).filectx(fn).renamed()
+ return repo[rev][fn].renamed()
except revlog.LookupError:
pass
return None
@@ -1869,17 +1856,13 @@
if not node:
node = rev
- m = repo.changectx(node).manifest()
- files = m.keys()
- files.sort()
-
- for f in files:
+ decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
+ ctx = repo[node]
+ for f in ctx:
if ui.debugflag:
- ui.write("%40s " % hex(m[f]))
+ ui.write("%40s " % hex(ctx.manifest()[f]))
if ui.verbose:
- type = m.execf(f) and "*" or m.linkf(f) and "@" or " "
- perm = m.execf(f) and "755" or "644"
- ui.write("%3s %1s " % (perm, type))
+ ui.write(decor[ctx.flags(f)])
ui.write("%s\n" % f)
def merge(ui, repo, node=None, force=None, rev=None):
@@ -1902,7 +1885,7 @@
node = rev
if not node:
- branch = repo.workingctx().branch()
+ branch = repo.changectx(None).branch()
bheads = repo.branchheads()
if len(bheads) > 2:
raise util.Abort(_("branch '%s' has %d heads - "
@@ -1916,7 +1899,7 @@
"please merge with an explicit rev") %
branch)
msg = _('there is nothing to merge')
- if parent != repo.lookup(repo.workingctx().branch()):
+ if parent != repo.lookup(repo[None].branch()):
msg = _('%s - use "hg update" instead') % msg
raise util.Abort(msg)
@@ -1973,9 +1956,9 @@
"""
rev = opts.get('rev')
if rev:
- ctx = repo.changectx(rev)
+ ctx = repo[rev]
else:
- ctx = repo.workingctx()
+ ctx = repo[None]
if file_:
m = cmdutil.match(repo, (file_,), opts)
@@ -2204,46 +2187,27 @@
raise util.Abort(_('no files specified'))
m = cmdutil.match(repo, pats, opts)
- mardu = map(dict.fromkeys, repo.status(match=m))[:5]
- modified, added, removed, deleted, unknown = mardu
-
- remove, forget = [], []
- for abs in repo.walk(m):
-
- reason = None
- if abs in removed or abs in unknown:
- continue
-
- # last column
- elif abs in deleted:
- remove.append(abs)
-
- # rest of the third row
- elif after and not force:
- reason = _('still exists (use -f to force removal)')
-
- # rest of the first column
- elif abs in added:
- if not force:
- reason = _('has been marked for add (use -f to force removal)')
- else:
- forget.append(abs)
-
- # rest of the third column
- elif abs in modified:
- if not force:
- reason = _('is modified (use -f to force removal)')
- else:
- remove.append(abs)
-
- # rest of the second column
- elif not reason:
- remove.append(abs)
-
- if reason:
- ui.warn(_('not removing %s: file %s\n') % (m.rel(abs), reason))
- elif ui.verbose or not m.exact(abs):
- ui.status(_('removing %s\n') % m.rel(abs))
+ s = repo.status(match=m, clean=True)
+ modified, added, deleted, clean = s[0], s[1], s[3], s[6]
+
+ def warn(files, reason):
+ for f in files:
+ ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
+ % (m.rel(f), reason))
+
+ if force:
+ remove, forget = modified + deleted + clean, added
+ elif after:
+ remove, forget = deleted, []
+ warn(modified + added + clean, _('still exists'))
+ else:
+ remove, forget = deleted + clean, []
+ warn(modified, _('is modified'))
+ warn(added, _('has been marked for add'))
+
+ for f in util.sort(remove + forget):
+ if ui.verbose or not m.exact(f):
+ ui.status(_('removing %s\n') % m.rel(f))
repo.forget(forget)
repo.remove(remove, unlink=not after)
@@ -2297,7 +2261,7 @@
elif opts.get("unmark"):
ms.mark(f, "u")
else:
- wctx = repo.workingctx()
+ wctx = repo[None]
mctx = wctx.parents()[-1]
ms.resolve(f, wctx, mctx)
@@ -2348,7 +2312,7 @@
if not opts['rev'] and p2 != nullid:
raise util.Abort(_('uncommitted merge - please provide a '
'specific revision'))
- ctx = repo.changectx(opts['rev'])
+ ctx = repo[opts['rev']]
node = ctx.node()
mf = ctx.manifest()
if node == parent:
@@ -2425,10 +2389,7 @@
(deleted, revert, remove, False, False),
)
- entries = names.items()
- entries.sort()
-
- for abs, (rel, exact) in entries:
+ for abs, (rel, exact) in util.sort(names.items()):
mfentry = mf.get(abs)
target = repo.wjoin(abs)
def handle(xlist, dobackup):
@@ -2466,7 +2427,7 @@
if pmf is None:
# only need parent manifest in this unlikely case,
# so do not read by default
- pmf = repo.changectx(parent).manifest()
+ pmf = repo[parent].manifest()
if abs in pmf:
if mfentry:
# if version of file is same in parent and target
@@ -2480,7 +2441,7 @@
if not opts.get('dry_run'):
def checkout(f):
fc = ctx[f]
- repo.wwrite(f, fc.data(), fc.fileflags())
+ repo.wwrite(f, fc.data(), fc.flags())
audit_path = util.path_auditor(repo.root)
for f in remove[0]:
@@ -2668,13 +2629,13 @@
changestates = zip(states, 'MAR!?IC', stat)
if (opts['all'] or opts['copies']) and not opts['no_status']:
- ctxn = repo.changectx(nullid)
- ctx1 = repo.changectx(node1)
- ctx2 = repo.changectx(node2)
+ ctxn = repo[nullid]
+ ctx1 = repo[node1]
+ ctx2 = repo[node2]
added = stat[1]
if node2 is None:
added = stat[0] + stat[1] # merged?
- ctx2 = repo.workingctx()
+
for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].items():
if k in added:
copy[k] = v
@@ -2713,7 +2674,7 @@
See 'hg help dates' for a list of formats valid for -d/--date.
"""
- rev_ = None
+ rev_ = "."
names = (name1,) + names
if len(names) != len(dict.fromkeys(names)):
raise util.Abort(_('tag names must be unique'))
@@ -2744,7 +2705,7 @@
if not rev_ and repo.dirstate.parents()[1] != nullid:
raise util.Abort(_('uncommitted merge - please provide a '
'specific revision'))
- r = repo.changectx(rev_).node()
+ r = repo[rev_].node()
if not message:
message = (_('Added tag %s for changeset %s') %
@@ -2801,7 +2762,7 @@
that repository becomes the current tip. The "tip" tag is special
and cannot be renamed or assigned to a different changeset.
"""
- cmdutil.show_changeset(ui, repo, opts).show(nullrev+repo.changelog.count())
+ cmdutil.show_changeset(ui, repo, opts).show(len(repo) - 1)
def unbundle(ui, repo, fname1, *fnames, **opts):
"""apply one or more changegroup files
--- a/mercurial/context.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/context.py Sat Jun 28 09:28:01 2008 +0200
@@ -12,19 +12,11 @@
class changectx(object):
"""A changecontext object makes access to data related to a particular
changeset convenient."""
- def __init__(self, repo, changeid=None):
+ def __init__(self, repo, changeid=''):
"""changeid is a revision number, node, or tag"""
+ if changeid == '':
+ changeid = '.'
self._repo = repo
-
- if not changeid and changeid != 0:
- p1, p2 = self._repo.dirstate.parents()
- self._rev = self._repo.changelog.rev(p1)
- if self._rev == -1:
- changeid = 'tip'
- else:
- self._node = p1
- return
-
self._node = self._repo.lookup(changeid)
self._rev = self._repo.changelog.rev(self._node)
@@ -63,6 +55,12 @@
md = self._repo.manifest.readdelta(self._changeset[0])
self._manifestdelta = md
return self._manifestdelta
+ elif name == '_parents':
+ p = self._repo.changelog.parents(self._node)
+ if p[1] == nullid:
+ p = p[:-1]
+ self._parents = [changectx(self._repo, x) for x in p]
+ return self._parents
else:
raise AttributeError, name
@@ -73,9 +71,7 @@
return self.filectx(key)
def __iter__(self):
- a = self._manifest.keys()
- a.sort()
- for f in a:
+ for f in util.sort(self._manifest):
yield f
def changeset(self): return self._changeset
@@ -93,8 +89,7 @@
def parents(self):
"""return contexts for each parent changeset"""
- p = self._repo.changelog.parents(self._node)
- return [changectx(self._repo, x) for x in p]
+ return self._parents
def children(self):
"""return contexts for each child changeset"""
@@ -121,7 +116,7 @@
def filenode(self, path):
return self._fileinfo(path)[0]
- def fileflags(self, path):
+ def flags(self, path):
try:
return self._fileinfo(path)[1]
except revlog.LookupError:
@@ -137,10 +132,7 @@
def filectxs(self):
"""generate a file context for each file in this changeset's
manifest"""
- mf = self.manifest()
- m = mf.keys()
- m.sort()
- for f in m:
+ for f in util.sort(mf):
yield self.filectx(f, fileid=mf[f])
def ancestor(self, c2):
@@ -240,9 +232,7 @@
def filerev(self): return self._filerev
def filenode(self): return self._filenode
- def fileflags(self): return self._changectx.fileflags(self._path)
- def isexec(self): return 'x' in self.fileflags()
- def islink(self): return 'l' in self.fileflags()
+ def flags(self): return self._changectx.flags(self._path)
def filelog(self): return self._filelog
def rev(self):
@@ -388,12 +378,11 @@
# sort by revision (per file) which is a topological order
visit = []
for f in files:
- fn = [(n.rev(), n) for n in needed.keys() if n._path == f]
+ fn = [(n.rev(), n) for n in needed if n._path == f]
visit.extend(fn)
- visit.sort()
+
hist = {}
-
- for r, f in visit:
+ for r, f in util.sort(visit):
curr = decorate(f.data(), f)
for p in parents(f):
if p != nullid:
@@ -468,7 +457,7 @@
self._user = self._repo.ui.username()
if parents:
p1, p2 = parents
- self._parents = [self._repo.changectx(p) for p in (p1, p2)]
+ self._parents = [changectx(self._repo, p) for p in (p1, p2)]
if changes:
self._status = list(changes)
@@ -492,15 +481,18 @@
return True
def __getattr__(self, name):
- if name == '_parents':
- self._parents = self._repo.parents()
- return self._parents
if name == '_status':
- self._status = self._repo.status()
+ self._status = self._repo.status(unknown=True)
return self._status
if name == '_manifest':
self._buildmanifest()
return self._manifest
+ elif name == '_parents':
+ p = self._repo.dirstate.parents()
+ if p[1] == nullid:
+ p = p[:-1]
+ self._parents = [changectx(self._repo, x) for x in p]
+ return self._parents
else:
raise AttributeError, name
@@ -509,16 +501,14 @@
man = self._parents[0].manifest().copy()
copied = self._repo.dirstate.copies()
- is_exec = util.execfunc(self._repo.root,
- lambda p: man.execf(copied.get(p,p)))
- is_link = util.linkfunc(self._repo.root,
- lambda p: man.linkf(copied.get(p,p)))
+ cf = lambda x: man.flags(copied.get(x, x))
+ ff = self._repo.dirstate.flagfunc(cf)
modified, added, removed, deleted, unknown = self._status[:5]
for i, l in (("a", added), ("m", modified), ("u", unknown)):
for f in l:
man[f] = man.get(copied.get(f, f), nullid) + i
try:
- man.set(f, is_exec(f), is_link(f))
+ man.set(f, ff(f))
except OSError:
pass
@@ -534,9 +524,7 @@
def date(self): return self._date
def description(self): return self._text
def files(self):
- f = self.modified() + self.added() + self.removed()
- f.sort()
- return f
+ return util.sort(self._status[0] + self._status[1] + self._status[2])
def modified(self): return self._status[0]
def added(self): return self._status[1]
@@ -552,14 +540,10 @@
[t.extend(p.tags()) for p in self.parents()]
return t
- def parents(self):
- """return contexts for each parent changeset"""
- return self._parents
-
def children(self):
return []
- def fileflags(self, path):
+ def flags(self, path):
if '_manifest' in self.__dict__:
try:
return self._manifest.flags(path)
@@ -569,12 +553,9 @@
pnode = self._parents[0].changeset()[0]
orig = self._repo.dirstate.copies().get(path, path)
node, flag = self._repo.manifest.find(pnode, orig)
- is_link = util.linkfunc(self._repo.root,
- lambda p: flag and 'l' in flag)
- is_exec = util.execfunc(self._repo.root,
- lambda p: flag and 'x' in flag)
try:
- return (is_link(path) and 'l' or '') + (is_exec(path) and 'x' or '')
+ ff = self._repo.dirstate.flagfunc(lambda x: flag or '')
+ return ff(path)
except OSError:
pass
@@ -698,9 +679,8 @@
self._user = user or self._repo.ui.username()
parents = [(p or nullid) for p in parents]
p1, p2 = parents
- self._parents = [self._repo.changectx(p) for p in (p1, p2)]
- files = list(files)
- files.sort()
+ self._parents = [changectx(self._repo, p) for p in (p1, p2)]
+ files = util.sort(list(files))
self._status = [files, [], [], [], []]
self._filectxfn = filectxfn
@@ -728,6 +708,7 @@
def clean(self): return self._status[5]
def branch(self): return self._extra['branch']
def extra(self): return self._extra
+ def flags(self, f): return self[f].flags()
def parents(self):
"""return contexts for each parent changeset"""
@@ -754,7 +735,7 @@
def __str__(self): return "%s@%s" % (self.path(), self._changectx)
def path(self): return self._path
def data(self): return self._data
- def fileflags(self): return self._flags
+ def flags(self): return self._flags
def isexec(self): return 'x' in self._flags
def islink(self): return 'l' in self._flags
def renamed(self): return self._copied
--- a/mercurial/copies.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/copies.py Sat Jun 28 09:28:01 2008 +0200
@@ -11,9 +11,7 @@
def _nonoverlap(d1, d2, d3):
"Return list of elements in d1 not in d2 or d3"
- l = [d for d in d1 if d not in d3 and d not in d2]
- l.sort()
- return l
+ return util.sort([d for d in d1 if d not in d3 and d not in d2])
def _dirname(f):
s = f.rfind("/")
@@ -49,9 +47,7 @@
visit += [(p, depth - 1) for p in fc.parents()]
# return old names sorted by depth
- old = old.values()
- old.sort()
- return [o[1] for o in old]
+ return [o[1] for o in util.sort(old.values())]
def _findlimit(repo, a, b):
"find the earliest revision that's an ancestor of a or b but not both"
@@ -67,7 +63,7 @@
# - quit when interesting revs is zero
cl = repo.changelog
- working = cl.count() # pseudo rev for the working directory
+ working = len(cl) # pseudo rev for the working directory
if a is None:
a = working
if b is None:
--- a/mercurial/dirstate.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/dirstate.py Sat Jun 28 09:28:01 2008 +0200
@@ -70,14 +70,17 @@
elif name == '_slash':
self._slash = self._ui.configbool('ui', 'slash') and os.sep != '/'
return self._slash
+ elif name == '_checklink':
+ self._checklink = util.checklink(self._root)
+ return self._checklink
elif name == '_checkexec':
self._checkexec = util.checkexec(self._root)
return self._checkexec
- elif name == '_folding':
- self._folding = not util.checkfolding(self._join('.hg'))
- return self._folding
+ elif name == '_checkcase':
+ self._checkcase = not util.checkcase(self._join('.hg'))
+ return self._checkcase
elif name == 'normalize':
- if self._folding:
+ if self._checkcase:
self.normalize = self._normalize
else:
self.normalize = lambda x: x
@@ -88,8 +91,33 @@
def _join(self, f):
return os.path.join(self._root, f)
- def folding(self):
- return self._folding
+ def flagfunc(self, fallback):
+ if self._checklink:
+ if self._checkexec:
+ def f(x):
+ p = os.path.join(self._root, x)
+ if os.path.islink(p):
+ return 'l'
+ if util.is_exec(p):
+ return 'x'
+ return ''
+ return f
+ def f(x):
+ if os.path.islink(os.path.join(self._root, x)):
+ return 'l'
+ if 'x' in fallback(x):
+ return 'x'
+ return ''
+ return f
+ if self._checkexec:
+ def f(x):
+ if 'l' in fallback(x):
+ return 'l'
+ if util.is_exec(os.path.join(self._root, x)):
+ return 'x'
+ return ''
+ return f
+ return fallback
def getcwd(self):
cwd = os.getcwd()
@@ -125,9 +153,7 @@
return key in self._map
def __iter__(self):
- a = self._map.keys()
- a.sort()
- for x in a:
+ for x in util.sort(self._map):
yield x
def parents(self):
@@ -356,7 +382,7 @@
def rebuild(self, parent, files):
self.clear()
for f in files:
- if files.execf(f):
+ if 'x' in files.flags(f):
self._map[f] = ('n', 0777, -1, 0, 0)
else:
self._map[f] = ('n', 0666, -1, 0, 0)
@@ -408,8 +434,7 @@
if not unknown:
return ret
- b = self._map.keys()
- b.sort()
+ b = util.sort(self._map)
blen = len(b)
for x in unknown:
@@ -447,12 +472,7 @@
return True
return False
- def walk(self, match):
- # filter out the src and stat
- for src, f, st in self.statwalk(match):
- yield f
-
- def statwalk(self, match, unknown=True, ignored=False):
+ def walk(self, match, unknown, ignored):
'''
walk recursively through the directory tree, finding all files
matched by the match function
@@ -537,9 +557,10 @@
continue
for f, kind, st in entries:
np = pconvert(join(nd, f))
+ nn = self.normalize(np)
if np in known:
continue
- known[np] = 1
+ known[nn] = 1
p = join(top, f)
# don't trip over symlinks
if kind == stat.S_IFDIR:
@@ -548,19 +569,18 @@
if hasattr(match, 'dir'):
match.dir(np)
if np in dc and match(np):
- add((np, 'm', st))
+ add((nn, 'm', st))
elif imatch(np):
if supported(np, st.st_mode):
- add((np, 'f', st))
+ add((nn, 'f', st))
elif np in dc:
- add((np, 'm', st))
- found.sort()
- return found
+ add((nn, 'm', st))
+ return util.sort(found)
# step one, find all files that match our criteria
- files.sort()
- for ff in files:
+ for ff in util.sort(files):
nf = normpath(ff)
+ nn = self.normalize(nf)
f = _join(ff)
try:
st = lstat(f)
@@ -581,9 +601,9 @@
for f, src, st in findfiles(f):
yield src, f, st
else:
- if nf in known:
+ if nn in known:
continue
- known[nf] = 1
+ known[nn] = 1
if match(nf):
if supported(ff, st.st_mode, verbose=True):
yield 'f', self.normalize(nf), st
@@ -592,16 +612,15 @@
# step two run through anything left in the dc hash and yield
# if we haven't already seen it
- ks = dc.keys()
- ks.sort()
- for k in ks:
+ for k in util.sort(dc):
if k in known:
continue
known[k] = 1
if imatch(k):
yield 'm', k, None
- def status(self, match, list_ignored, list_clean, list_unknown):
+ def status(self, match, ignored, clean, unknown):
+ listignored, listclean, listunknown = ignored, clean, unknown
lookup, modified, added, unknown, ignored = [], [], [], [], []
removed, deleted, clean = [], [], []
@@ -618,13 +637,12 @@
dadd = deleted.append
cadd = clean.append
- for src, fn, st in self.statwalk(match, unknown=list_unknown,
- ignored=list_ignored):
+ for src, fn, st in self.walk(match, listunknown, listignored):
if fn not in dmap:
- if (list_ignored or match.exact(fn)) and self._dirignore(fn):
- if list_ignored:
+ if (listignored or match.exact(fn)) and self._dirignore(fn):
+ if listignored:
iadd(fn)
- elif list_unknown:
+ elif listunknown:
uadd(fn)
continue
@@ -657,7 +675,7 @@
madd(fn)
elif time != int(st.st_mtime):
ladd(fn)
- elif list_clean:
+ elif listclean:
cadd(fn)
elif state == 'm':
madd(fn)
--- a/mercurial/filemerge.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/filemerge.py Sat Jun 28 09:28:01 2008 +0200
@@ -63,8 +63,7 @@
if t not in tools:
tools[t] = int(_toolstr(ui, t, "priority", "0"))
names = tools.keys()
- tools = [(-p,t) for t,p in tools.items()]
- tools.sort()
+ tools = util.sort([(-p,t) for t,p in tools.items()])
uimerge = ui.config("ui", "merge")
if uimerge:
if uimerge not in names:
@@ -132,7 +131,7 @@
ui = repo.ui
fd = fcd.path()
binary = isbin(fcd) or isbin(fco) or isbin(fca)
- symlink = fcd.islink() or fco.islink()
+ symlink = 'l' in fcd.flags() + fco.flags()
tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
ui.debug(_("picked tool '%s' for %s (binary %s symlink %s)\n") %
(tool, fd, binary, symlink))
@@ -146,7 +145,7 @@
if tool == "internal:local":
return 0
if tool == "internal:other":
- repo.wwrite(fd, fco.data(), fco.fileflags())
+ repo.wwrite(fd, fco.data(), fco.flags())
return 0
if tool == "internal:fail":
return 1
@@ -180,9 +179,9 @@
env = dict(HG_FILE=fd,
HG_MY_NODE=short(mynode),
HG_OTHER_NODE=str(fco.changectx()),
- HG_MY_ISLINK=fcd.islink(),
- HG_OTHER_ISLINK=fco.islink(),
- HG_BASE_ISLINK=fca.islink())
+ HG_MY_ISLINK='l' in fcd.flags(),
+ HG_OTHER_ISLINK='l' in fco.flags(),
+ HG_BASE_ISLINK='l' in fca.flags())
if tool == "internal:merge":
r = simplemerge.simplemerge(a, b, c, label=['local', 'other'])
--- a/mercurial/graphmod.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/graphmod.py Sat Jun 28 09:28:01 2008 +0200
@@ -69,6 +69,6 @@
edges.append((col, next.index(p), colors[p]))
# Yield and move on
- yield (repo.changectx(curr_rev), (idx, color), edges)
+ yield (repo[curr_rev], (idx, color), edges)
revs = next
curr_rev -= 1
--- a/mercurial/hbisect.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/hbisect.py Sat Jun 28 09:28:01 2008 +0200
@@ -20,12 +20,12 @@
badrev = min([changelog.rev(n) for n in bad])
goodrevs = [changelog.rev(n) for n in good]
# build ancestors array
- ancestors = [[]] * (changelog.count() + 1) # an extra for [-1]
+ ancestors = [[]] * (len(changelog) + 1) # an extra for [-1]
# clear good revs from array
for node in goodrevs:
ancestors[node] = None
- for rev in xrange(changelog.count(), -1, -1):
+ for rev in xrange(len(changelog), -1, -1):
if ancestors[rev] is None:
for prev in clparents(rev):
ancestors[prev] = None
@@ -60,7 +60,6 @@
children[prev] = [rev]
visit.append(prev)
- candidates.sort()
# have we narrowed it down to one entry?
tot = len(candidates)
if tot == 1:
@@ -71,7 +70,7 @@
best_rev = None
best_len = -1
poison = {}
- for rev in candidates:
+ for rev in util.sort(candidates):
if rev in poison:
for c in children.get(rev, []):
poison[c] = True # poison children
--- a/mercurial/hgweb/hgweb_mod.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/hgweb/hgweb_mod.py Sat Jun 28 09:28:01 2008 +0200
@@ -306,8 +306,8 @@
linenumber="% 8s" % lineno)
r = self.repo
- c1 = r.changectx(node1)
- c2 = r.changectx(node2)
+ c1 = r[node1]
+ c2 = r[node2]
date1 = util.datestr(c1.date())
date2 = util.datestr(c2.date())
--- a/mercurial/hgweb/hgwebdir_mod.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/hgweb/hgwebdir_mod.py Sat Jun 28 09:28:01 2008 +0200
@@ -19,8 +19,8 @@
class hgwebdir(object):
def __init__(self, config, parentui=None):
def cleannames(items):
- return [(util.pconvert(name).strip('/'), path)
- for name, path in items]
+ return util.sort([(util.pconvert(name).strip('/'), path)
+ for name, path in items])
self.parentui = parentui or ui.ui(report_untrusted=False,
interactive = False)
@@ -34,7 +34,6 @@
self.repos_sorted = ('', False)
elif isinstance(config, dict):
self.repos = cleannames(config.items())
- self.repos.sort()
else:
if isinstance(config, util.configparser):
cp = config
--- a/mercurial/hgweb/webcommands.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/hgweb/webcommands.py Sat Jun 28 09:28:01 2008 +0200
@@ -13,7 +13,7 @@
from mercurial.repo import RepoError
from common import paritygen, staticfile, get_contact, ErrorResponse
from common import HTTP_OK, HTTP_NOT_FOUND
-from mercurial import graphmod
+from mercurial import graphmod, util
# __all__ is populated with the allowed commands. Be sure to add to it if
# you're adding a new command, or the new command won't work.
@@ -110,10 +110,10 @@
qw = query.lower().split()
def revgen():
- for i in xrange(cl.count() - 1, 0, -100):
+ for i in xrange(len(cl) - 1, 0, -100):
l = []
for j in xrange(max(0, i - 100), i + 1):
- ctx = web.repo.changectx(j)
+ ctx = web.repo[j]
l.append(ctx)
l.reverse()
for e in l:
@@ -168,9 +168,9 @@
if 'rev' in req.form:
hi = req.form['rev'][0]
else:
- hi = web.repo.changelog.count() - 1
+ hi = len(web.repo) - 1
try:
- ctx = web.repo.changectx(hi)
+ ctx = web.repo[hi]
except RepoError:
return _search(web, tmpl, hi) # XXX redirect to 404 page?
@@ -178,7 +178,7 @@
cl = web.repo.changelog
l = [] # build a list in forward order for efficiency
for i in xrange(start, end):
- ctx = web.repo.changectx(i)
+ ctx = web.repo[i]
n = ctx.node()
showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
@@ -205,7 +205,7 @@
maxchanges = shortlog and web.maxshortchanges or web.maxchanges
cl = web.repo.changelog
- count = cl.count()
+ count = len(cl)
pos = ctx.rev()
start = max(0, pos - maxchanges + 1)
end = min(count, start + maxchanges)
@@ -288,9 +288,7 @@
raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
def filelist(**map):
- fl = files.keys()
- fl.sort()
- for f in fl:
+ for f in util.sort(files):
full, fnode = files[f]
if not fnode:
continue
@@ -299,14 +297,12 @@
yield {"file": full,
"parity": parity.next(),
"basename": f,
- "date": fctx.changectx().date(),
+ "date": fctx.date(),
"size": fctx.size(),
"permissions": mf.flags(full)}
def dirlist(**map):
- fl = files.keys()
- fl.sort()
- for f in fl:
+ for f in util.sort(files):
full, fnode = files[f]
if fnode:
continue
@@ -343,7 +339,7 @@
count = count + 1
yield {"parity": parity.next(),
"tag": k,
- "date": web.repo.changectx(n).date(),
+ "date": web.repo[n].date(),
"node": hex(n)}
return tmpl("tags",
@@ -371,27 +367,24 @@
parity=parity.next(),
tag=k,
node=hex(n),
- date=web.repo.changectx(n).date())
+ date=web.repo[n].date())
def branches(**map):
parity = paritygen(web.stripecount)
b = web.repo.branchtags()
l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.items()]
- l.sort()
-
- for r,n,t in l:
- ctx = web.repo.changectx(n)
+ for r,n,t in util.sort(l):
yield {'parity': parity.next(),
'branch': t,
'node': hex(n),
- 'date': ctx.date()}
+ 'date': web.repo[n].date()}
def changelist(**map):
parity = paritygen(web.stripecount, offset=start-end)
l = [] # build a list in forward order for efficiency
for i in xrange(start, end):
- ctx = web.repo.changectx(i)
+ ctx = web.repo[i]
n = ctx.node()
hn = hex(n)
@@ -410,7 +403,7 @@
yield l
cl = web.repo.changelog
- count = cl.count()
+ count = len(cl)
start = max(0, count - web.maxchanges)
end = min(count, start + web.maxchanges)
@@ -499,7 +492,7 @@
fctx = webutil.filectx(web.repo, req)
f = fctx.path()
fl = fctx.filelog()
- count = fl.count()
+ count = len(fl)
pagelen = web.maxshortchanges
pos = fctx.filerev()
start = max(0, pos - pagelen + 1)
@@ -580,7 +573,7 @@
rev = webutil.changectx(web.repo, req).rev()
bg_height = 39
- max_rev = web.repo.changelog.count() - 1
+ max_rev = len(web.repo) - 1
revcount = min(max_rev, int(req.form.get('revcount', [25])[0]))
revnode = web.repo.changelog.node(rev)
revnode_hex = hex(revnode)
@@ -589,7 +582,7 @@
lessrev = max(0, rev - revcount / 2)
maxchanges = web.maxshortchanges or web.maxchanges
- count = web.repo.changelog.count()
+ count = len(web.repo)
changenav = webutil.revnavgen(rev, maxchanges, count, web.repo.changectx)
tree = list(graphmod.graph(web.repo, rev, rev - revcount))
--- a/mercurial/hgweb/webutil.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/hgweb/webutil.py Sat Jun 28 09:28:01 2008 +0200
@@ -112,19 +112,17 @@
return util.canonpath(repo.root, '', path)
def changectx(repo, req):
+ changeid = "tip"
if 'node' in req.form:
changeid = req.form['node'][0]
elif 'manifest' in req.form:
changeid = req.form['manifest'][0]
- else:
- changeid = repo.changelog.count() - 1
try:
- ctx = repo.changectx(changeid)
+ ctx = repo[changeid]
except RepoError:
man = repo.manifest
- mn = man.lookup(changeid)
- ctx = repo.changectx(man.linkrev(mn))
+ ctx = repo[man.linkrev(man.lookup(changeid))]
return ctx
@@ -135,8 +133,7 @@
else:
changeid = req.form['filenode'][0]
try:
- ctx = repo.changectx(changeid)
- fctx = ctx.filectx(path)
+ fctx = repo[changeid][path]
except RepoError:
fctx = repo.filectx(path, fileid=changeid)
--- a/mercurial/hook.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/hook.py Sat Jun 28 09:28:01 2008 +0200
@@ -96,10 +96,9 @@
oldstdout = os.dup(sys.__stdout__.fileno())
os.dup2(sys.__stderr__.fileno(), sys.__stdout__.fileno())
- hooks = [(hname, cmd) for hname, cmd in ui.configitems("hooks")
- if hname.split(".", 1)[0] == name and cmd]
- hooks.sort()
- for hname, cmd in hooks:
+ for hname, cmd in util.sort(ui.configitems('hooks')):
+ if hname.split('.')[0] != name or not cmd:
+ continue
if callable(cmd):
r = _pythonhook(ui, repo, name, hname, cmd, args, throw) or r
elif cmd.startswith('python:'):
--- a/mercurial/localrepo.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/localrepo.py Sat Jun 28 09:28:01 2008 +0200
@@ -117,6 +117,21 @@
else:
raise AttributeError, name
+ def __getitem__(self, changeid):
+ if changeid == None:
+ return context.workingctx(self)
+ return context.changectx(self, changeid)
+
+ def __nonzero__(self):
+ return True
+
+ def __len__(self):
+ return len(self.changelog)
+
+ def __iter__(self):
+ for i in xrange(len(self)):
+ yield i
+
def url(self):
return 'file:' + self.root
@@ -330,7 +345,7 @@
last = {}
ret = []
for node in heads:
- c = self.changectx(node)
+ c = self[node]
rev = c.rev()
try:
fnode = c.filenode('.hgtags')
@@ -351,8 +366,7 @@
except:
r = -2 # sort to the beginning of the list if unknown
l.append((r, t, n))
- l.sort()
- return [(t, n) for r, t, n in l]
+ return [(t, n) for r, t, n in util.sort(l)]
def nodetags(self, node):
'''return the tags associated with a node'''
@@ -363,7 +377,7 @@
return self.nodetagscache.get(node, [])
def _branchtags(self, partial, lrev):
- tiprev = self.changelog.count() - 1
+ tiprev = len(self) - 1
if lrev != tiprev:
self._updatebranchcache(partial, lrev+1, tiprev+1)
self._writebranchcache(partial, self.changelog.tip(), tiprev)
@@ -408,8 +422,7 @@
try:
last, lrev = lines.pop(0).split(" ", 1)
last, lrev = bin(last), int(lrev)
- if not (lrev < self.changelog.count() and
- self.changelog.node(lrev) == last): # sanity check
+ if lrev >= len(self) or self[lrev].node() != last:
# invalidate the cache
raise ValueError('invalidating branch cache (tip differs)')
for l in lines:
@@ -436,18 +449,13 @@
def _updatebranchcache(self, partial, start, end):
for r in xrange(start, end):
- c = self.changectx(r)
+ c = self[r]
b = c.branch()
partial[b] = c.node()
def lookup(self, key):
if key == '.':
- key, second = self.dirstate.parents()
- if key == nullid:
- raise repo.RepoError(_("no revision checked out"))
- if second != nullid:
- self.ui.warn(_("warning: working directory has two parents, "
- "tag '.' uses the first\n"))
+ return self.dirstate.parents()[0]
elif key == 'null':
return nullid
n = self.changelog._match(key)
@@ -488,24 +496,12 @@
f = f[1:]
return filelog.filelog(self.sopener, f)
- def changectx(self, changeid=None):
- return context.changectx(self, changeid)
-
- def workingctx(self):
- return context.workingctx(self)
+ def changectx(self, changeid):
+ return self[changeid]
def parents(self, changeid=None):
- '''
- get list of changectxs for parents of changeid or working directory
- '''
- if changeid is None:
- pl = self.dirstate.parents()
- else:
- n = self.changelog.lookup(changeid)
- pl = self.changelog.parents(n)
- if pl[1] == nullid:
- return [self.changectx(pl[0])]
- return [self.changectx(pl[0]), self.changectx(pl[1])]
+ '''get list of changectxs for parents of changeid'''
+ return self[changeid].parents()
def filectx(self, path, changeid=None, fileid=None):
"""changeid can be a changeset revision, node, or tag.
@@ -814,7 +810,7 @@
tr = None
valid = 0 # don't save the dirstate if this isn't set
try:
- commit = wctx.modified() + wctx.added()
+ commit = util.sort(wctx.modified() + wctx.added())
remove = wctx.removed()
extra = wctx.extra().copy()
branchname = extra['branch']
@@ -846,25 +842,21 @@
# check in files
new = {}
changed = []
- linkrev = self.changelog.count()
- commit.sort()
+ linkrev = len(self)
for f in commit:
self.ui.note(f + "\n")
try:
fctx = wctx.filectx(f)
+ newflags = fctx.flags()
new[f] = self.filecommit(fctx, m1, m2, linkrev, trp, changed)
- new_exec = fctx.isexec()
- new_link = fctx.islink()
if ((not changed or changed[-1] != f) and
m2.get(f) != new[f]):
# mention the file in the changelog if some
# flag changed, even if there was no content
# change.
- old_exec = m1.execf(f)
- old_link = m1.linkf(f)
- if old_exec != new_exec or old_link != new_link:
+ if m1.flags(f) != newflags:
changed.append(f)
- m1.set(f, new_exec, new_link)
+ m1.set(f, newflags)
if use_dirstate:
self.dirstate.normal(f)
@@ -877,10 +869,9 @@
# update manifest
m1.update(new)
- remove.sort()
removed = []
- for f in remove:
+ for f in util.sort(remove):
if f in m1:
del m1[f]
removed.append(f)
@@ -956,10 +947,7 @@
# for dirstate.walk, files=['.'] means "walk the whole tree".
# follow that here, too
fdict.pop('.', None)
- mdict = self.manifest.read(self.changelog.read(node)[0])
- mfiles = mdict.keys()
- mfiles.sort()
- for fn in mfiles:
+ for fn in self[node]:
for ffn in fdict:
# match if the file is the exact name or a directory
if ffn == fn or fn.startswith("%s/" % ffn):
@@ -967,18 +955,16 @@
break
if match(fn):
yield fn
- ffiles = fdict.keys()
- ffiles.sort()
- for fn in ffiles:
+ for fn in util.sort(fdict):
if match.bad(fn, 'No such file in rev ' + short(node)) \
and match(fn):
yield fn
else:
- for fn in self.dirstate.walk(match):
+ for src, fn, st in self.dirstate.walk(match, True, False):
yield fn
def status(self, node1=None, node2=None, match=None,
- list_ignored=False, list_clean=False, list_unknown=True):
+ ignored=False, clean=False, unknown=False):
"""return status of files between two nodes or node and working directory
If node1 is None, use the first dirstate parent instead.
@@ -1000,6 +986,7 @@
if not match:
match = match_.always(self.root, self.getcwd())
+ listignored, listclean, listunknown = ignored, clean, unknown
modified, added, removed, deleted, unknown = [], [], [], [], []
ignored, clean = [], []
@@ -1016,27 +1003,22 @@
# are we comparing the working directory?
if not node2:
(lookup, modified, added, removed, deleted, unknown,
- ignored, clean) = self.dirstate.status(match, list_ignored,
- list_clean, list_unknown)
+ ignored, clean) = self.dirstate.status(match, listignored,
+ listclean, listunknown)
# are we comparing working dir against its parent?
if compareworking:
if lookup:
fixup = []
# do a full compare of any files that might have changed
- ctx = self.changectx()
- mexec = lambda f: 'x' in ctx.fileflags(f)
- mlink = lambda f: 'l' in ctx.fileflags(f)
- is_exec = util.execfunc(self.root, mexec)
- is_link = util.linkfunc(self.root, mlink)
- def flags(f):
- return is_link(f) and 'l' or is_exec(f) and 'x' or ''
+ ctx = self['.']
+ ff = self.dirstate.flagfunc(ctx.flags)
for f in lookup:
- if (f not in ctx or flags(f) != ctx.fileflags(f)
+ if (f not in ctx or ff(f) != ctx.flags(f)
or ctx[f].cmp(self.wread(f))):
modified.append(f)
else:
fixup.append(f)
- if list_clean:
+ if listclean:
clean.append(f)
# update dirstate for files that are actually clean
@@ -1057,11 +1039,10 @@
# generate a pseudo-manifest for the working dir
# XXX: create it in dirstate.py ?
mf2 = mfmatches(self.dirstate.parents()[0])
- is_exec = util.execfunc(self.root, mf2.execf)
- is_link = util.linkfunc(self.root, mf2.linkf)
+ ff = self.dirstate.flagfunc(mf2.flags)
for f in lookup + modified + added:
mf2[f] = ""
- mf2.set(f, is_exec(f), is_link(f))
+ mf2.set(f, ff(f))
for f in removed:
if f in mf2:
del mf2[f]
@@ -1076,16 +1057,14 @@
# make sure to sort the files so we talk to the disk in a
# reasonable order
- mf2keys = mf2.keys()
- mf2keys.sort()
getnode = lambda fn: mf1.get(fn, nullid)
- for fn in mf2keys:
+ for fn in util.sort(mf2):
if fn in mf1:
if (mf1.flags(fn) != mf2.flags(fn) or
(mf1[fn] != mf2[fn] and
(mf2[fn] != "" or fcmp(fn, getnode)))):
modified.append(fn)
- elif list_clean:
+ elif listclean:
clean.append(fn)
del mf1[fn]
else:
@@ -1201,11 +1180,11 @@
heads = self.changelog.heads(start)
# sort the output in rev descending order
heads = [(-self.changelog.rev(h), h) for h in heads]
- heads.sort()
- return [n for (r, n) in heads]
+ return [n for (r, n) in util.sort(heads)]
def branchheads(self, branch=None, start=None):
- branch = branch is None and self.workingctx().branch() or branch
+ if branch is None:
+ branch = self[None].branch()
branches = self.branchtags()
if branch not in branches:
return []
@@ -1243,7 +1222,7 @@
if rev in ancestors:
ancestors.update(self.changelog.parentrevs(rev))
ancestors.remove(rev)
- elif self.changectx(rev).branch() == branch:
+ elif self[rev].branch() == branch:
heads.append(rev)
ancestors.update(self.changelog.parentrevs(rev))
heads = [self.changelog.node(rev) for rev in heads]
@@ -1658,7 +1637,7 @@
# Nor do we know which filenodes are missing.
msng_filenode_set = {}
- junk = mnfst.index[mnfst.count() - 1] # Get around a bug in lazyindex
+ junk = mnfst.index[len(mnfst) - 1] # Get around a bug in lazyindex
junk = None
# A changeset always belongs to itself, so the changenode lookup
@@ -1853,12 +1832,10 @@
add_extra_nodes(fname,
msng_filenode_set.setdefault(fname, {}))
changedfiles[fname] = 1
- changedfiles = changedfiles.keys()
- changedfiles.sort()
# Go through all our files in order sorted by name.
- for fname in changedfiles:
+ for fname in util.sort(changedfiles):
filerevlog = self.file(fname)
- if filerevlog.count() == 0:
+ if not len(filerevlog):
raise util.Abort(_("empty or missing revlog for %s") % fname)
# Toss out the filenodes that the recipient isn't really
# missing.
@@ -1909,10 +1886,10 @@
def identity(x):
return x
- def gennodelst(revlog):
- for r in xrange(0, revlog.count()):
- n = revlog.node(r)
- if revlog.linkrev(n) in revset:
+ def gennodelst(log):
+ for r in log:
+ n = log.node(r)
+ if log.linkrev(n) in revset:
yield n
def changed_file_collector(changedfileset):
@@ -1934,17 +1911,15 @@
for chnk in cl.group(nodes, identity,
changed_file_collector(changedfiles)):
yield chnk
- changedfiles = changedfiles.keys()
- changedfiles.sort()
mnfst = self.manifest
nodeiter = gennodelst(mnfst)
for chnk in mnfst.group(nodeiter, lookuprevlink_func(mnfst)):
yield chnk
- for fname in changedfiles:
+ for fname in util.sort(changedfiles):
filerevlog = self.file(fname)
- if filerevlog.count() == 0:
+ if not len(filerevlog):
raise util.Abort(_("empty or missing revlog for %s") % fname)
nodeiter = gennodelst(filerevlog)
nodeiter = list(nodeiter)
@@ -1973,7 +1948,7 @@
"""
def csmap(x):
self.ui.debug(_("add changeset %s\n") % short(x))
- return cl.count()
+ return len(cl)
def revmap(x):
return cl.rev(x)
@@ -1996,11 +1971,11 @@
trp = weakref.proxy(tr)
# pull off the changeset group
self.ui.status(_("adding changesets\n"))
- cor = cl.count() - 1
+ cor = len(cl) - 1
chunkiter = changegroup.chunkiter(source)
if cl.addgroup(chunkiter, csmap, trp) is None and not emptyok:
raise util.Abort(_("received changelog group is empty"))
- cnr = cl.count() - 1
+ cnr = len(cl) - 1
changesets = cnr - cor
# pull off the manifest group
@@ -2020,11 +1995,11 @@
break
self.ui.debug(_("adding %s revisions\n") % f)
fl = self.file(f)
- o = fl.count()
+ o = len(fl)
chunkiter = changegroup.chunkiter(source)
if fl.addgroup(chunkiter, revmap, trp) is None:
raise util.Abort(_("received file revlog group is empty"))
- revisions += fl.count() - o
+ revisions += len(fl) - o
files += 1
# make changelog see real files again
--- a/mercurial/manifest.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/manifest.py Sat Jun 28 09:28:01 2008 +0200
@@ -8,7 +8,7 @@
from node import bin, hex, nullid
from revlog import revlog, RevlogError
from i18n import _
-import array, struct, mdiff, parsers
+import array, struct, mdiff, parsers, util
class manifestdict(dict):
def __init__(self, mapping=None, flags=None):
@@ -18,16 +18,8 @@
self._flags = flags
def flags(self, f):
return self._flags.get(f, "")
- def execf(self, f):
- "test for executable in manifest flags"
- return "x" in self.flags(f)
- def linkf(self, f):
- "test for symlink in manifest flags"
- return "l" in self.flags(f)
- def set(self, f, execf=False, linkf=False):
- if linkf: self._flags[f] = "l"
- elif execf: self._flags[f] = "x"
- else: self._flags[f] = ""
+ def set(self, f, flags):
+ self._flags[f] = flags
def copy(self):
return manifestdict(dict.copy(self), dict.copy(self._flags))
@@ -134,9 +126,7 @@
# if we're using the listcache, make sure it is valid and
# parented by the same node we're diffing against
if not (changed and self.listcache and p1 and self.mapcache[0] == p1):
- files = map.keys()
- files.sort()
-
+ files = util.sort(map)
for f in files:
checkforbidden(f)
--- a/mercurial/merge.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/merge.py Sat Jun 28 09:28:01 2008 +0200
@@ -262,11 +262,10 @@
"apply the merge action list to the working directory"
updated, merged, removed, unresolved = 0, 0, 0, 0
- action.sort()
-
ms = mergestate(repo)
ms.reset(wctx.parents()[0].node())
moves = []
+ action.sort()
# prescan for merges
for a in action:
@@ -409,7 +408,7 @@
wlock = repo.wlock()
try:
- wc = repo.workingctx()
+ wc = repo[None]
if node is None:
# tip of current branch
try:
@@ -421,7 +420,7 @@
raise util.Abort(_("branch %s not found") % wc.branch())
overwrite = force and not branchmerge
pl = wc.parents()
- p1, p2 = pl[0], repo.changectx(node)
+ p1, p2 = pl[0], repo[node]
pa = p1.ancestor(p2)
fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
fastforward = False
@@ -460,7 +459,7 @@
action = []
if not force:
_checkunknown(wc, p2)
- if not util.checkfolding(repo.path):
+ if not util.checkcase(repo.path):
_checkcollision(p2)
action += _forgetremoved(wc, p2, branchmerge)
action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
--- a/mercurial/patch.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/patch.py Sat Jun 28 09:28:01 2008 +0200
@@ -8,7 +8,7 @@
from i18n import _
from node import hex, nullid, short
-import base85, cmdutil, mdiff, util, context, revlog, diffhelpers, copies
+import base85, cmdutil, mdiff, util, revlog, diffhelpers, copies
import cStringIO, email.Parser, os, popen2, re, errno
import sys, tempfile, zlib
@@ -1039,9 +1039,12 @@
continue
elif state == 'git':
gitpatches = values
+ cwd = os.getcwd()
for gp in gitpatches:
if gp.op in ('COPY', 'RENAME'):
- copyfile(gp.oldpath, gp.path)
+ src, dst = [util.canonpath(cwd, cwd, x)
+ for x in [gp.oldpath, gp.path]]
+ copyfile(src, dst)
changed[gp.path] = (gp.op, gp)
else:
raise util.Abort(_('unsupported parser state: %s') % state)
@@ -1091,8 +1094,7 @@
repo.copy(src, dst)
removes = removes.keys()
if removes:
- removes.sort()
- repo.remove(removes, True)
+ repo.remove(util.sort(removes), True)
for f in patches:
ctype, gp = patches[f]
if gp and gp.mode:
@@ -1110,9 +1112,7 @@
cmdutil.addremove(repo, cfiles)
files = patches.keys()
files.extend([r for r in removes if r not in files])
- files.sort()
-
- return files
+ return util.sort(files)
def b85diff(to, tn):
'''print base85-encoded binary diff'''
@@ -1180,30 +1180,19 @@
# reading the data for node1 early allows it to play nicely
# with repo.status and the revlog cache.
- ctx1 = context.changectx(repo, node1)
+ ctx1 = repo[node1]
# force manifest reading
man1 = ctx1.manifest()
date1 = util.datestr(ctx1.date())
if not changes:
- changes = repo.status(node1, node2, match=match)[:5]
- modified, added, removed, deleted, unknown = changes
+ changes = repo.status(node1, node2, match=match)
+ modified, added, removed = changes[:3]
if not modified and not added and not removed:
return
- if node2:
- ctx2 = context.changectx(repo, node2)
- execf2 = ctx2.manifest().execf
- linkf2 = ctx2.manifest().linkf
- else:
- ctx2 = context.workingctx(repo)
- execf2 = util.execfunc(repo.root, None)
- linkf2 = util.linkfunc(repo.root, None)
- if execf2 is None:
- mc = ctx2.parents()[0].manifest().copy()
- execf2 = mc.execf
- linkf2 = mc.linkf
+ ctx2 = repo[node2]
if repo.ui.quiet:
r = None
@@ -1212,15 +1201,14 @@
r = [hexfunc(node) for node in [node1, node2] if node]
if opts.git:
- copy, diverge = copies.copies(repo, ctx1, ctx2, repo.changectx(nullid))
+ copy, diverge = copies.copies(repo, ctx1, ctx2, repo[nullid])
for k, v in copy.items():
copy[v] = k
- all = modified + added + removed
- all.sort()
gone = {}
+ gitmode = {'l': '120000', 'x': '100755', '': '100644'}
- for f in all:
+ for f in util.sort(modified + added + removed):
to = None
tn = None
dodiff = True
@@ -1231,18 +1219,16 @@
tn = getfilectx(f, ctx2).data()
a, b = f, f
if opts.git:
- def gitmode(x, l):
- return l and '120000' or (x and '100755' or '100644')
def addmodehdr(header, omode, nmode):
if omode != nmode:
header.append('old mode %s\n' % omode)
header.append('new mode %s\n' % nmode)
if f in added:
- mode = gitmode(execf2(f), linkf2(f))
+ mode = gitmode[ctx2.flags(f)]
if f in copy:
a = copy[f]
- omode = gitmode(man1.execf(a), man1.linkf(a))
+ omode = gitmode[man1.flags(a)]
addmodehdr(header, omode, mode)
if a in removed and a not in gone:
op = 'rename'
@@ -1261,11 +1247,11 @@
if f in copy and copy[f] in added and copy[copy[f]] == f:
dodiff = False
else:
- mode = gitmode(man1.execf(f), man1.linkf(f))
- header.append('deleted file mode %s\n' % mode)
+ header.append('deleted file mode %s\n' %
+ gitmode[man1.flags(f)])
else:
- omode = gitmode(man1.execf(f), man1.linkf(f))
- nmode = gitmode(execf2(f), linkf2(f))
+ omode = gitmode[man1.flags(f)]
+ nmode = gitmode[ctx2.flags(f)]
addmodehdr(header, omode, nmode)
if util.binary(to) or util.binary(tn):
dodiff = 'binary'
@@ -1291,7 +1277,7 @@
revwidth = max([len(str(rev)) for rev in revs])
def single(rev, seqno, fp):
- ctx = repo.changectx(rev)
+ ctx = repo[rev]
node = ctx.node()
parents = [p.node() for p in ctx.parents() if p]
branch = ctx.branch()
--- a/mercurial/repair.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/repair.py Sat Jun 28 09:28:01 2008 +0200
@@ -23,8 +23,8 @@
"""find out the filelogs affected by the strip"""
files = {}
- for x in xrange(striprev, repo.changelog.count()):
- for name in repo.changectx(x).files():
+ for x in xrange(striprev, len(repo)):
+ for name in repo[x].files():
if name in files:
continue
files[name] = 1
@@ -37,7 +37,7 @@
"""return the nodes that have to be saved before the strip"""
def collectone(revlog):
extra = []
- startrev = count = revlog.count()
+ startrev = count = len(revlog)
# find the truncation point of the revlog
for i in xrange(0, count):
node = revlog.node(i)
@@ -84,7 +84,7 @@
tostrip = {striprev: 1}
saveheads = {}
savebases = []
- for r in xrange(striprev + 1, cl.count()):
+ for r in xrange(striprev + 1, len(cl)):
parents = cl.parentrevs(r)
if parents[0] in tostrip or parents[1] in tostrip:
# r is a descendant of striprev
--- a/mercurial/revlog.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/revlog.py Sat Jun 28 09:28:01 2008 +0200
@@ -515,9 +515,11 @@
def tip(self):
return self.node(len(self.index) - 2)
- def count(self):
+ def __len__(self):
return len(self.index) - 1
-
+ def __iter__(self):
+ for i in xrange(len(self)):
+ yield i
def rev(self, node):
try:
return self.nodemap[node]
@@ -620,12 +622,11 @@
lowestrev = nullrev
if (lowestrev == nullrev) and (heads is None):
# We want _all_ the nodes!
- return ([self.node(r) for r in xrange(0, self.count())],
- [nullid], list(self.heads()))
+ return ([self.node(r) for r in self], [nullid], list(self.heads()))
if heads is None:
# All nodes are ancestors, so the latest ancestor is the last
# node.
- highestrev = self.count() - 1
+ highestrev = len(self) - 1
# Set ancestors to None to signal that every node is an ancestor.
ancestors = None
# Set heads to an empty dictionary for later discovery of heads
@@ -754,15 +755,15 @@
as if they had no children
"""
if start is None and stop is None:
- count = self.count()
+ count = len(self)
if not count:
return [nullid]
ishead = [1] * (count + 1)
index = self.index
- for r in xrange(count):
+ for r in self:
e = index[r]
ishead[e[5]] = ishead[e[6]] = 0
- return [self.node(r) for r in xrange(count) if ishead[r]]
+ return [self.node(r) for r in self if ishead[r]]
if start is None:
start = nullid
@@ -774,7 +775,7 @@
heads = {startrev: 1}
parentrevs = self.parentrevs
- for r in xrange(startrev + 1, self.count()):
+ for r in xrange(startrev + 1, len(self)):
for p in parentrevs(r):
if p in reachable:
if r not in stoprevs:
@@ -789,7 +790,7 @@
"""find the children of a given node"""
c = []
p = self.rev(node)
- for r in range(p + 1, self.count()):
+ for r in range(p + 1, len(self)):
prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
if prevs:
for pr in prevs:
@@ -818,8 +819,8 @@
if str(rev) != id:
raise ValueError
if rev < 0:
- rev = self.count() + rev
- if rev < 0 or rev >= self.count():
+ rev = len(self) + rev
+ if rev < 0 or rev >= len(self):
raise ValueError
return self.node(rev)
except (ValueError, OverflowError):
@@ -982,7 +983,7 @@
df = self.opener(self.datafile, 'w')
try:
calc = self._io.size
- for r in xrange(self.count()):
+ for r in self:
start = self.start(r) + (r + 1) * calc
length = self.length(r)
fp.seek(start)
@@ -995,7 +996,7 @@
fp = self.opener(self.indexfile, 'w', atomictemp=True)
self.version &= ~(REVLOGNGINLINEDATA)
self._inline = False
- for i in xrange(self.count()):
+ for i in self:
e = self._io.packentry(self.index[i], self.node, self.version, i)
fp.write(e)
@@ -1031,7 +1032,7 @@
if node in self.nodemap:
return node
- curr = self.count()
+ curr = len(self)
prev = curr - 1
base = self.base(prev)
offset = self.end(prev)
@@ -1146,7 +1147,7 @@
"""
#track the base of the current delta log
- r = self.count()
+ r = len(self)
t = r - 1
node = None
@@ -1265,13 +1266,13 @@
trust that the caller has saved the revisions that shouldn't be
removed and that it'll readd them after this truncation.
"""
- if self.count() == 0:
+ if len(self) == 0:
return
if isinstance(self.index, lazyindex):
self._loadindexmap()
- for rev in xrange(0, self.count()):
+ for rev in self:
if self.index[rev][4] >= minlink:
break
else:
@@ -1292,15 +1293,15 @@
# then reset internal state in memory to forget those revisions
self._cache = None
self._chunkcache = None
- for x in xrange(rev, self.count()):
+ for x in xrange(rev, len(self)):
del self.nodemap[self.node(x)]
del self.index[rev:-1]
def checksize(self):
expected = 0
- if self.count():
- expected = max(0, self.end(self.count() - 1))
+ if len(self):
+ expected = max(0, self.end(len(self) - 1))
try:
f = self.opener(self.datafile)
@@ -1321,10 +1322,10 @@
di = actual - (i * s)
if self._inline:
databytes = 0
- for r in xrange(self.count()):
+ for r in self:
databytes += max(0, self.length(r))
dd = 0
- di = actual - self.count() * s - databytes
+ di = actual - len(self) * s - databytes
except IOError, inst:
if inst.errno != errno.ENOENT:
raise
--- a/mercurial/streamclone.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/streamclone.py Sat Jun 28 09:28:01 2008 +0200
@@ -34,8 +34,7 @@
for x in walk(os.path.join(root, 'data'), True):
yield x
# write manifest before changelog
- meta = list(walk(root, False))
- meta.sort()
+ meta = util.sort(walk(root, False))
meta.reverse()
for x in meta:
yield x
--- a/mercurial/ui.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/ui.py Sat Jun 28 09:28:01 2008 +0200
@@ -312,15 +312,11 @@
items = self._configitems(section, untrusted=untrusted, abort=True)
if self.debugflag and not untrusted and self.ucdata:
uitems = self._configitems(section, untrusted=True, abort=False)
- keys = uitems.keys()
- keys.sort()
- for k in keys:
+ for k in util.sort(uitems):
if uitems[k] != items.get(k):
self.warn(_("Ignoring untrusted configuration option "
"%s.%s = %s\n") % (section, k, uitems[k]))
- x = items.items()
- x.sort()
- return x
+ return util.sort(items.items())
def walkconfig(self, untrusted=False):
cdata = self._get_cdata(untrusted)
--- a/mercurial/util.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/util.py Sat Jun 28 09:28:01 2008 +0200
@@ -252,6 +252,12 @@
"""return the uniq elements of iterable g"""
return dict.fromkeys(g).keys()
+def sort(l):
+ if not isinstance(l, list):
+ l = list(l)
+ l.sort()
+ return l
+
class Abort(Exception):
"""Raised if a command needs to print an error and exit."""
@@ -839,7 +845,7 @@
# File system features
-def checkfolding(path):
+def checkcase(path):
"""
Check whether the given path is on a case-sensitive filesystem
@@ -933,12 +939,6 @@
return False
return not (new_file_has_exec or exec_flags_cannot_flip)
-def execfunc(path, fallback):
- '''return an is_exec() function with default to fallback'''
- if checkexec(path):
- return lambda x: is_exec(os.path.join(path, x))
- return fallback
-
def checklink(path):
"""check whether the given path is on a symlink-capable filesystem"""
# mktemp is not racy because symlink creation will fail if the
@@ -951,12 +951,6 @@
except (OSError, AttributeError):
return False
-def linkfunc(path, fallback):
- '''return an is_link() function with default to fallback'''
- if checklink(path):
- return lambda x: os.path.islink(os.path.join(path, x))
- return fallback
-
_umask = os.umask(0)
os.umask(_umask)
--- a/mercurial/verify.py Thu Jun 26 13:37:47 2008 -0700
+++ b/mercurial/verify.py Sat Jun 28 09:28:01 2008 +0200
@@ -7,7 +7,7 @@
from node import nullid, short
from i18n import _
-import revlog
+import revlog, util
def verify(repo):
lock = repo.lock()
@@ -17,265 +17,201 @@
del lock
def _verify(repo):
+ mflinkrevs = {}
filelinkrevs = {}
filenodes = {}
- changesets = revisions = files = 0
- firstbad = [None]
+ revisions = 0
+ badrevs = {}
errors = [0]
warnings = [0]
- neededmanifests = {}
+ ui = repo.ui
+ cl = repo.changelog
+ mf = repo.manifest
def err(linkrev, msg, filename=None):
if linkrev != None:
- if firstbad[0] != None:
- firstbad[0] = min(firstbad[0], linkrev)
- else:
- firstbad[0] = linkrev
+ badrevs[linkrev] = True
else:
- linkrev = "?"
+ linkrev = '?'
msg = "%s: %s" % (linkrev, msg)
if filename:
msg = "%s@%s" % (filename, msg)
- repo.ui.warn(" " + msg + "\n")
+ ui.warn(" " + msg + "\n")
errors[0] += 1
+ def exc(linkrev, msg, inst, filename=None):
+ if isinstance(inst, KeyboardInterrupt):
+ ui.warn(_("interrupted"))
+ raise
+ err(linkrev, "%s: %s" % (msg, inst), filename)
+
def warn(msg):
- repo.ui.warn(msg + "\n")
+ ui.warn(msg + "\n")
warnings[0] += 1
- def checksize(obj, name):
+ def checklog(obj, name):
+ if not len(obj) and (havecl or havemf):
+ err(0, _("empty or missing %s") % name)
+ return
+
d = obj.checksize()
if d[0]:
err(None, _("data length off by %d bytes") % d[0], name)
if d[1]:
err(None, _("index contains %d extra bytes") % d[1], name)
- def checkversion(obj, name):
if obj.version != revlog.REVLOGV0:
if not revlogv1:
warn(_("warning: `%s' uses revlog format 1") % name)
elif revlogv1:
warn(_("warning: `%s' uses revlog format 0") % name)
- revlogv1 = repo.changelog.version != revlog.REVLOGV0
- if repo.ui.verbose or not revlogv1:
- repo.ui.status(_("repository uses revlog format %d\n") %
+ def checkentry(obj, i, node, seen, linkrevs, f):
+ lr = obj.linkrev(node)
+ if lr < 0 or (havecl and lr not in linkrevs):
+ t = "unexpected"
+ if lr < 0 or lr >= len(cl):
+ t = "nonexistent"
+ err(None, _("rev %d point to %s changeset %d") % (i, t, lr), f)
+ if linkrevs:
+ warn(_(" (expected %s)") % " ".join(map(str,linkrevs)))
+ lr = None # can't be trusted
+
+ try:
+ p1, p2 = obj.parents(node)
+ if p1 not in seen and p1 != nullid:
+ err(lr, _("unknown parent 1 %s of %s") %
+ (short(p1), short(n)), f)
+ if p2 not in seen and p2 != nullid:
+ err(lr, _("unknown parent 2 %s of %s") %
+ (short(p2), short(p1)), f)
+ except Exception, inst:
+ exc(lr, _("checking parents of %s") % short(node), inst, f)
+
+ if node in seen:
+ err(lr, _("duplicate revision %d (%d)") % (i, seen[n]), f)
+ seen[n] = i
+ return lr
+
+ revlogv1 = cl.version != revlog.REVLOGV0
+ if ui.verbose or not revlogv1:
+ ui.status(_("repository uses revlog format %d\n") %
(revlogv1 and 1 or 0))
- havecl = havemf = 1
- seen = {}
- repo.ui.status(_("checking changesets\n"))
- if repo.changelog.count() == 0 and repo.manifest.count() > 1:
- havecl = 0
- err(0, _("empty or missing 00changelog.i"))
- else:
- checksize(repo.changelog, "changelog")
-
- for i in xrange(repo.changelog.count()):
- changesets += 1
- n = repo.changelog.node(i)
- l = repo.changelog.linkrev(n)
- if l != i:
- err(i, _("incorrect link (%d) for changeset") %(l))
- if n in seen:
- err(i, _("duplicates changeset at revision %d") % seen[n])
- seen[n] = i
-
- for p in repo.changelog.parents(n):
- if p not in repo.changelog.nodemap:
- err(i, _("changeset has unknown parent %s") % short(p))
- try:
- changes = repo.changelog.read(n)
- except KeyboardInterrupt:
- repo.ui.warn(_("interrupted"))
- raise
- except Exception, inst:
- err(i, _("unpacking changeset: %s") % inst)
- continue
+ havecl = len(cl) > 0
+ havemf = len(mf) > 0
- if changes[0] not in neededmanifests:
- neededmanifests[changes[0]] = i
-
- for f in changes[3]:
- filelinkrevs.setdefault(f, []).append(i)
-
+ ui.status(_("checking changesets\n"))
seen = {}
- repo.ui.status(_("checking manifests\n"))
- if repo.changelog.count() > 0 and repo.manifest.count() == 0:
- havemf = 0
- err(0, _("empty or missing 00manifest.i"))
- else:
- checkversion(repo.manifest, "manifest")
- checksize(repo.manifest, "manifest")
-
- for i in xrange(repo.manifest.count()):
- n = repo.manifest.node(i)
- l = repo.manifest.linkrev(n)
-
- if l < 0 or (havecl and l >= repo.changelog.count()):
- err(None, _("bad link (%d) at manifest revision %d") % (l, i))
-
- if n in neededmanifests:
- del neededmanifests[n]
-
- if n in seen:
- err(l, _("duplicates manifest from %d") % seen[n])
-
- seen[n] = l
-
- for p in repo.manifest.parents(n):
- if p not in repo.manifest.nodemap:
- err(l, _("manifest has unknown parent %s") % short(p))
+ checklog(cl, "changelog")
+ for i in repo:
+ n = cl.node(i)
+ checkentry(cl, i, n, seen, [i], "changelog")
try:
- for f, fn in repo.manifest.readdelta(n).iteritems():
- fns = filenodes.setdefault(f, {})
- if fn not in fns:
- fns[fn] = n
- except KeyboardInterrupt:
- repo.ui.warn(_("interrupted"))
- raise
+ changes = cl.read(n)
+ mflinkrevs.setdefault(changes[0], []).append(i)
+ for f in changes[3]:
+ filelinkrevs.setdefault(f, []).append(i)
except Exception, inst:
- err(l, _("reading manifest delta: %s") % inst)
- continue
-
- repo.ui.status(_("crosschecking files in changesets and manifests\n"))
+ exc(i, _("unpacking changeset %s") % short(n), inst)
- if havemf > 0:
- nm = [(c, m) for m, c in neededmanifests.items()]
- nm.sort()
- for c, m in nm:
- err(c, _("changeset refers to unknown manifest %s") % short(m))
- del neededmanifests, nm
+ ui.status(_("checking manifests\n"))
+ seen = {}
+ checklog(mf, "manifest")
+ for i in mf:
+ n = mf.node(i)
+ lr = checkentry(mf, i, n, seen, mflinkrevs.get(n, []), "manifest")
+ if n in mflinkrevs:
+ del mflinkrevs[n]
- if havecl:
- fl = filenodes.keys()
- fl.sort()
- for f in fl:
- if f not in filelinkrevs:
- lrs = [repo.manifest.linkrev(n) for n in filenodes[f]]
- lrs.sort()
- err(lrs[0], _("in manifest but not in changeset"), f)
- del fl
+ try:
+ for f, fn in mf.readdelta(n).iteritems():
+ if not f:
+ err(lr, _("file without name in manifest"))
+ elif f != "/dev/null":
+ fns = filenodes.setdefault(f, {})
+ if fn not in fns:
+ fns[fn] = n
+ except Exception, inst:
+ exc(lr, _("reading manifest delta %s") % short(n), inst)
+
+ ui.status(_("crosschecking files in changesets and manifests\n"))
if havemf:
- fl = filelinkrevs.keys()
- fl.sort()
- for f in fl:
+ for c, m in util.sort([(c, m) for m in mflinkrevs for c in mflinkrevs[m]]):
+ err(c, _("changeset refers to unknown manifest %s") % short(m))
+ del mflinkrevs
+
+ for f in util.sort(filelinkrevs):
if f not in filenodes:
lr = filelinkrevs[f][0]
err(lr, _("in changeset but not in manifest"), f)
- del fl
- repo.ui.status(_("checking files\n"))
- ff = dict.fromkeys(filenodes.keys() + filelinkrevs.keys()).keys()
- ff.sort()
- for f in ff:
- if f == "/dev/null":
- continue
- files += 1
- if not f:
- lr = filelinkrevs[f][0]
- err(lr, _("file without name in manifest"))
- continue
+ if havecl:
+ for f in util.sort(filenodes):
+ if f not in filelinkrevs:
+ try:
+ lr = min([repo.file(f).linkrev(n) for n in filenodes[f]])
+ except:
+ lr = None
+ err(lr, _("in manifest but not in changeset"), f)
+
+ ui.status(_("checking files\n"))
+ files = util.sort(util.unique(filenodes.keys() + filelinkrevs.keys()))
+ for f in files:
fl = repo.file(f)
- checkversion(fl, f)
- checksize(fl, f)
-
- if fl.count() == 0:
- err(filelinkrevs[f][0], _("empty or missing revlog"), f)
- continue
-
+ checklog(fl, f)
seen = {}
- nodes = {nullid: 1}
- for i in xrange(fl.count()):
+ for i in fl:
revisions += 1
n = fl.node(i)
- flr = fl.linkrev(n)
-
- if flr < 0 or (havecl and flr not in filelinkrevs.get(f, [])):
- if flr < 0 or flr >= repo.changelog.count():
- err(None, _("rev %d point to nonexistent changeset %d")
- % (i, flr), f)
- else:
- err(None, _("rev %d points to unexpected changeset %d")
- % (i, flr), f)
- if f in filelinkrevs:
- warn(_(" (expected %s)") % filelinkrevs[f][0])
- flr = None # can't be trusted
- else:
- if havecl:
- filelinkrevs[f].remove(flr)
-
- if n in seen:
- err(flr, _("duplicate revision %d") % i, f)
+ lr = checkentry(fl, i, n, seen, filelinkrevs.get(f, []), f)
if f in filenodes:
if havemf and n not in filenodes[f]:
- err(flr, _("%s not in manifests") % (short(n)), f)
+ err(lr, _("%s not in manifests") % (short(n)), f)
else:
del filenodes[f][n]
# verify contents
try:
t = fl.read(n)
- except KeyboardInterrupt:
- repo.ui.warn(_("interrupted"))
- raise
+ rp = fl.renamed(n)
+ if len(t) != fl.size(i):
+ if not fl._readmeta(n): # ancient copy?
+ err(lr, _("unpacked size is %s, %s expected") %
+ (len(t), fl.size(i)), f)
except Exception, inst:
- err(flr, _("unpacking %s: %s") % (short(n), inst), f)
-
- # verify parents
- try:
- (p1, p2) = fl.parents(n)
- if p1 not in nodes:
- err(flr, _("unknown parent 1 %s of %s") %
- (short(p1), short(n)), f)
- if p2 not in nodes:
- err(flr, _("unknown parent 2 %s of %s") %
- (short(p2), short(p1)), f)
- except KeyboardInterrupt:
- repo.ui.warn(_("interrupted"))
- raise
- except Exception, inst:
- err(flr, _("checking parents of %s: %s") % (short(n), inst), f)
- nodes[n] = 1
+ exc(lr, _("unpacking %s") % short(n), inst, f)
# check renames
try:
- rp = fl.renamed(n)
if rp:
fl2 = repo.file(rp[0])
- if fl2.count() == 0:
- err(flr, _("empty or missing copy source revlog %s:%s")
+ if not len(fl2):
+ err(lr, _("empty or missing copy source revlog %s:%s")
% (rp[0], short(rp[1])), f)
elif rp[1] == nullid:
- err(flr, _("copy source revision is nullid %s:%s")
+ err(lr, _("copy source revision is nullid %s:%s")
% (rp[0], short(rp[1])), f)
else:
rev = fl2.rev(rp[1])
- except KeyboardInterrupt:
- repo.ui.warn(_("interrupted"))
- raise
except Exception, inst:
- err(flr, _("checking rename of %s: %s") %
- (short(n), inst), f)
+ exc(lr, _("checking rename of %s") % short(n), inst, f)
# cross-check
if f in filenodes:
- fns = [(repo.manifest.linkrev(filenodes[f][n]), n)
- for n in filenodes[f]]
- fns.sort()
- for lr, node in fns:
+ fns = [(mf.linkrev(l), n) for n,l in filenodes[f].items()]
+ for lr, node in util.sort(fns):
err(lr, _("%s in manifests not found") % short(node), f)
- repo.ui.status(_("%d files, %d changesets, %d total revisions\n") %
- (files, changesets, revisions))
-
+ ui.status(_("%d files, %d changesets, %d total revisions\n") %
+ (len(files), len(cl), revisions))
if warnings[0]:
- repo.ui.warn(_("%d warnings encountered!\n") % warnings[0])
+ ui.warn(_("%d warnings encountered!\n") % warnings[0])
if errors[0]:
- repo.ui.warn(_("%d integrity errors encountered!\n") % errors[0])
- if firstbad[0]:
- repo.ui.warn(_("(first damaged changeset appears to be %d)\n")
- % firstbad[0])
+ ui.warn(_("%d integrity errors encountered!\n") % errors[0])
+ if badrevs:
+ ui.warn(_("(first damaged changeset appears to be %d)\n")
+ % min(badrevs))
return 1
--- a/tests/test-children.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-children.out Sat Jun 28 09:28:01 2008 +0200
@@ -5,6 +5,18 @@
% hg children at revision 3 (tip)
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
% hg children at nullrev (should be 0 and 3)
+changeset: 0:4df8521a7374
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+summary: 0
+
+changeset: 3:e2962852269d
+tag: tip
+parent: -1:000000000000
+user: test
+date: Thu Jan 01 00:00:03 1970 +0000
+summary: 3
+
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
% hg children at revision 1 (should be 2)
changeset: 2:8f5eea5023c2
--- a/tests/test-context.py Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-context.py Sat Jun 28 09:28:01 2008 +0200
@@ -16,4 +16,4 @@
repo.add(['foo'])
repo.commit(text='commit1', date="0 0")
-print "workingfilectx.date =", repo.workingctx().filectx('foo').date()
+print "workingfilectx.date =", repo[None]['foo'].date()
--- a/tests/test-convert-filemap Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-convert-filemap Sat Jun 28 09:28:01 2008 +0200
@@ -80,6 +80,7 @@
echo "include $i" >> "$fmap"
done
hg -q convert $opts --filemap "$fmap" --datesort source "$repo"
+ hg up -q -R "$repo"
glog -R "$repo"
hg -R "$repo" manifest --debug
}
@@ -115,6 +116,7 @@
rename copied copied2
EOF
hg -q convert --filemap renames.fmap --datesort source renames.repo
+hg up -q -R renames.repo
glog -R renames.repo
hg -R renames.repo manifest --debug
hg --cwd renames.repo debugrename copied2
--- a/tests/test-convert-filemap.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-convert-filemap.out Sat Jun 28 09:28:01 2008 +0200
@@ -29,7 +29,7 @@
copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
% foo: skip unwanted merges; use 1st parent in 1st merge, 2nd in 2nd
-o 3 "8: change foo" files: foo
+@ 3 "8: change foo" files: foo
|
o 2 "6: change foo baz" files: foo
|
@@ -39,7 +39,7 @@
9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
% bar: merges are not merges anymore
-o 4 "7: second merge; change bar" files: bar
+@ 4 "7: second merge; change bar" files: bar
|
o 3 "5: change bar baz quux" files: bar
|
@@ -51,7 +51,7 @@
9463f52fe115e377cf2878d4fc548117211063f2 644 bar
% baz: 1st merge is not a merge anymore; 2nd still is
-o 4 "7: second merge; change bar" files: baz
+@ 4 "7: second merge; change bar" files: baz
|\
| o 3 "6: change foo baz" files: baz
| |
@@ -63,7 +63,7 @@
94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
% foo quux: we add additional merges when they are interesting
-o 8 "8: change foo" files: foo
+@ 8 "8: change foo" files: foo
|
o 7 "7: second merge; change bar" files:
|\
@@ -84,14 +84,14 @@
9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
% bar quux: partial conversion
-o 1 "3: change bar quux" files: bar quux
+@ 1 "3: change bar quux" files: bar quux
|
o 0 "1: add bar quux; copy foo to copied" files: bar quux
b79105bedc55102f394e90a789c9c380117c1b4a 644 bar
db0421cc6b685a458c8d86c7d5c004f94429ea23 644 quux
% bar quux: complete the partial conversion
-o 4 "7: second merge; change bar" files: bar
+@ 4 "7: second merge; change bar" files: bar
|
o 3 "5: change bar baz quux" files: bar quux
|
@@ -104,11 +104,11 @@
9463f52fe115e377cf2878d4fc548117211063f2 644 bar
bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
% foo: partial conversion
-o 0 "0: add foo baz dir/" files: foo
+@ 0 "0: add foo baz dir/" files: foo
2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 foo
% foo: complete the partial conversion
-o 3 "8: change foo" files: foo
+@ 3 "8: change foo" files: foo
|
o 2 "6: change foo baz" files: foo
|
@@ -118,12 +118,12 @@
9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
% copied: copied file; source not included in new repo
-o 0 "1: add bar quux; copy foo to copied" files: copied
+@ 0 "1: add bar quux; copy foo to copied" files: copied
2ed2a3912a0b24502043eae84ee4b279c18b90dd 644 copied
copied not renamed
% foo copied: copied file; source included in new repo
-o 4 "8: change foo" files: foo
+@ 4 "8: change foo" files: foo
|
o 3 "6: change foo baz" files: foo
|
@@ -136,7 +136,7 @@
6ca237634e1f6bee1b6db94292fb44f092a25842 644 copied
9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
copied renamed from foo:2ed2a3912a0b24502043eae84ee4b279c18b90dd
-o 4 "8: change foo" files: foo2
+@ 4 "8: change foo" files: foo2
|
o 3 "6: change foo baz" files: foo2
|
--- a/tests/test-convert-git Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-convert-git Sat Jun 28 09:28:01 2008 +0200
@@ -53,7 +53,7 @@
cd ..
hg convert --datesort git-repo
-
+hg up -q -R git-repo-hg
hg -R git-repo-hg tip -v
count=10
@@ -117,12 +117,14 @@
echo "include $i" >> "$fmap"
done
hg -q convert $opts --filemap "$fmap" --datesort git-repo2 "$repo"
+ hg up -q -R "$repo"
glog -R "$repo"
hg -R "$repo" manifest --debug
}
echo '% full conversion'
hg -q convert --datesort git-repo2 fullrepo
+hg up -q -R fullrepo
glog -R fullrepo
hg -R fullrepo manifest --debug
--- a/tests/test-convert-git.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-convert-git.out Sat Jun 28 09:28:01 2008 +0200
@@ -24,7 +24,7 @@
% full conversion
-o 9 "Discard change to foo" files: foo
+@ 9 "Discard change to foo" files: foo
|\
| o 8 "change foo" files: foo
| |
@@ -49,7 +49,7 @@
9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
88dfeab657e8cf2cef3dec67b914f49791ae76b1 644 quux
% foo bar baz: octopus merge
-o 8 "Discard change to foo" files: foo
+@ 8 "Discard change to foo" files: foo
|\
| o 7 "change foo" files: foo
| |
@@ -71,7 +71,7 @@
354ae8da6e890359ef49ade27b68bbc361f3ca88 644 baz
9277c9cc8dd4576fc01a17939b4351e5ada93466 644 foo
% foo baz quux: only some parents of an octopus merge; "discard" a head
-o 6 "Discard change to foo" files: foo
+@ 6 "Discard change to foo" files: foo
|
o 5 "change foo" files: foo
|
--- a/tests/test-import Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-import Sat Jun 28 09:28:01 2008 +0200
@@ -261,3 +261,15 @@
hg status
cat a
cd ..
+
+echo % 'test paths outside repo root'
+mkdir outside
+touch outside/foo
+hg init inside
+cd inside
+hg import - <<EOF
+diff --git a/a b/b
+rename from ../outside/foo
+rename to bar
+EOF
+cd ..
--- a/tests/test-import.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-import.out Sat Jun 28 09:28:01 2008 +0200
@@ -260,3 +260,6 @@
adding a
applying patch from stdin
bb
+% test paths outside repo root
+applying patch from stdin
+abort: ../outside/foo not under root
--- a/tests/test-log.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-log.out Sat Jun 28 09:28:01 2008 +0200
@@ -150,7 +150,6 @@
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
% log -r . with two parents
-warning: working directory has two parents, tag '.' uses the first
changeset: 3:e62f78d544b4
parent: 1:3d5bf5654eda
user: test
--- a/tests/test-manifest Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-manifest Sat Jun 28 09:28:01 2008 +0200
@@ -14,6 +14,10 @@
hg init
hg -q pull "$TESTDIR/test-manifest.hg"
+echo % should be empty
+hg manifest
+
+hg co
hg manifest
hg manifest -v
hg manifest --debug
--- a/tests/test-manifest.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-manifest.out Sat Jun 28 09:28:01 2008 +0200
@@ -1,3 +1,5 @@
+% should be empty
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
a
b/a
l
--- a/tests/test-merge-remove.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-merge-remove.out Sat Jun 28 09:28:01 2008 +0200
@@ -23,7 +23,6 @@
M foo1
foo
% reverting foo1 and bar
-warning: working directory has two parents, tag '.' uses the first
saving current version of bar as bar.orig
reverting bar
saving current version of foo1 as foo1.orig
--- a/tests/test-parseindex Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-parseindex Sat Jun 28 09:28:01 2008 +0200
@@ -44,8 +44,8 @@
return wrapper
cl = changelog.changelog(opener('.hg/store'))
-print cl.count(), 'revisions:'
-for r in xrange(cl.count()):
+print len(cl), 'revisions:'
+for r in cl:
print short(cl.node(r))
EOF
--- a/tests/test-purge Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-purge Sat Jun 28 09:28:01 2008 +0200
@@ -83,23 +83,15 @@
rm r1
# hide error messages to avoid changing the output when the text changes
hg purge -p 2> /dev/null
-if [ $? -ne 0 ]; then
- echo "refused to run"
-fi
-if [ -f untracked_file ]; then
- echo "untracked_file still around"
-fi
-hg purge -p --force
+hg st
+
+hg purge -p
hg purge -v 2> /dev/null
-if [ $? -ne 0 ]; then
- echo "refused to run"
-fi
-if [ -f untracked_file ]; then
- echo "untracked_file still around"
-fi
-hg purge -v --force
+hg st
+
+hg purge -v
hg revert --all --quiet
-ls
+hg st -a
echo '% tracked file in ignored directory (issue621)'
echo directory >> .hgignore
--- a/tests/test-purge.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-purge.out Sat Jun 28 09:28:01 2008 +0200
@@ -51,14 +51,12 @@
directory
r1
% abort with missing files until we support name mangling filesystems
-refused to run
-untracked_file still around
untracked_file
-refused to run
-untracked_file still around
+! r1
+? untracked_file
+untracked_file
Removing file untracked_file
-directory
-r1
+! r1
% tracked file in ignored directory (issue621)
untracked_file
Removing file untracked_file
--- a/tests/test-remove.out Thu Jun 26 13:37:47 2008 -0700
+++ b/tests/test-remove.out Sat Jun 28 09:28:01 2008 +0200
@@ -70,15 +70,15 @@
adding test/bar
adding test/foo
% dir, options none
+removing test/bar
removing test/foo
-removing test/bar
R test/bar
R test/foo
./foo
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
% dir, options -f
+removing test/bar
removing test/foo
-removing test/bar
R test/bar
R test/foo
./foo
@@ -91,8 +91,8 @@
./test/foo
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% dir, options -Af
+removing test/bar
removing test/foo
-removing test/bar
R test/bar
R test/foo
./foo