Mercurial > hg
changeset 2567:2748253b49c2
Merge context patches
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 05 Jul 2006 13:28:25 -0500 |
parents | bf67d0f6531c (current diff) d8560b458f76 (diff) |
children | 82e3b2966862 52ce0d6bc375 |
files | mercurial/commands.py mercurial/localrepo.py |
diffstat | 4 files changed, 162 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py Tue Jul 04 15:36:05 2006 -0700 +++ b/mercurial/commands.py Wed Jul 05 13:28:25 2006 -0500 @@ -248,11 +248,11 @@ seen[rev] = 1 yield str(rev) -def make_filename(repo, r, pat, node=None, +def make_filename(repo, pat, node, total=None, seqno=None, revwidth=None, pathname=None): node_expander = { 'H': lambda: hex(node), - 'R': lambda: str(r.rev(node)), + 'R': lambda: str(repo.changelog.rev(node)), 'h': lambda: short(node), } expander = { @@ -292,7 +292,7 @@ raise util.Abort(_("invalid format spec '%%%s' in output file name"), inst.args[0]) -def make_file(repo, r, pat, node=None, +def make_file(repo, pat, node=None, total=None, seqno=None, revwidth=None, mode='wb', pathname=None): if not pat or pat == '-': return 'w' in mode and sys.stdout or sys.stdin @@ -300,7 +300,7 @@ return pat if hasattr(pat, 'read') and 'r' in mode: return pat - return open(make_filename(repo, r, pat, node, total, seqno, revwidth, + return open(make_filename(repo, pat, node, total, seqno, revwidth, pathname), mode) @@ -741,15 +741,18 @@ ucache = {} def getname(rev): - cl = repo.changelog.read(repo.changelog.node(rev)) - return trimuser(ui, cl[1], rev, ucache) + try: + return ucache[rev] + except: + u = trimuser(ui, repo.changectx(rev).user(), rev, ucache) + ucache[rev] = u + return u dcache = {} def getdate(rev): datestr = dcache.get(rev) if datestr is None: - cl = repo.changelog.read(repo.changelog.node(rev)) - datestr = dcache[rev] = util.datestr(cl[2]) + datestr = dcache[rev] = util.datestr(repo.changectx(rev).date()) return datestr if not pats: @@ -760,20 +763,15 @@ if not opts['user'] and not opts['changeset'] and not opts['date']: opts['number'] = 1 - if opts['rev']: - node = repo.changelog.lookup(opts['rev']) - else: - node = repo.dirstate.parents()[0] - change = repo.changelog.read(node) - mmap = repo.manifest.read(change[0]) + ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) for src, abs, rel, exact in walk(repo, pats, opts, node=node): - f = repo.file(abs) - if not opts['text'] and util.binary(f.read(mmap[abs])): + fctx = ctx.filectx(abs) + if not opts['text'] and util.binary(fctx.data()): ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) continue - lines = f.annotate(mmap[abs]) + lines = fctx.annotate() pieces = [] for o, f in opmap: @@ -819,7 +817,7 @@ raise util.Abort(_('uncommitted merge - please provide a ' 'specific revision')) - dest = make_filename(repo, repo.changelog, dest, node) + dest = make_filename(repo, dest, node) if os.path.realpath(dest) == repo.root: raise util.Abort(_('repository root cannot be destination')) dummy, matchfn, dummy = matchpats(repo, [], opts) @@ -830,7 +828,7 @@ raise util.Abort(_('cannot archive plain files to stdout')) dest = sys.stdout if not prefix: prefix = os.path.basename(repo.root) + '-%h' - prefix = make_filename(repo, repo.changelog, prefix, node) + prefix = make_filename(repo, prefix, node) archival.archive(repo, dest, node, kind, not opts['no_decode'], matchfn, prefix) @@ -920,19 +918,10 @@ %d dirname of file being printed, or '.' if in repo root %p root-relative path name of file being printed """ - mf = {} - rev = opts['rev'] - if rev: - node = repo.lookup(rev) - else: - node = repo.changelog.tip() - change = repo.changelog.read(node) - mf = repo.manifest.read(change[0]) - for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, node): - r = repo.file(abs) - n = mf[abs] - fp = make_file(repo, r, opts['output'], node=n, pathname=abs) - fp.write(r.read(n)) + ctx = repo.changectx(opts['rev'] or -1) + for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, ctx.node()): + fp = make_file(repo, opts['output'], ctx.node(), pathname=abs) + fp.write(ctx.filectx(abs).data()) def clone(ui, source, dest=None, **opts): """make a copy of an existing repository @@ -1501,8 +1490,7 @@ prev = (parents and parents[0]) or nullid change = repo.changelog.read(node) - fp = make_file(repo, repo.changelog, opts['output'], - node=node, total=total, seqno=seqno, + fp = make_file(repo, opts['output'], node, total=total, seqno=seqno, revwidth=revwidth) if fp != sys.stdout: ui.note("%s\n" % fp.name)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/context.py Wed Jul 05 13:28:25 2006 -0500 @@ -0,0 +1,124 @@ +# context.py - changeset and file context objects for mercurial +# +# Copyright 2005 Matt Mackall <mpm@selenic.com> +# +# This software may be used and distributed according to the terms +# of the GNU General Public License, incorporated herein by reference. + +class changectx(object): + """A changecontext object makes access to data related to a particular + changeset convenient.""" + def __init__(self, repo, changeid): + """changeid is a revision number, node, or tag""" + self._repo = repo + self._id = changeid + + self._node = self._repo.lookup(self._id) + self._rev = self._repo.changelog.rev(self._node) + + def changeset(self): + try: + return self._changeset + except AttributeError: + self._changeset = self._repo.changelog.read(self.node()) + return self._changeset + + def manifest(self): + try: + return self._manifest + except AttributeError: + self._manifest = self._repo.manifest.read(self.changeset()[0]) + return self._manifest + + def rev(self): return self._rev + def node(self): return self._node + def user(self): return self.changeset()[1] + def date(self): return self.changeset()[2] + def changedfiles(self): return self.changeset()[3] + def description(self): return self.changeset()[4] + + 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 ] + + def children(self): + """return contexts for each child changeset""" + c = self.repo.changelog.children(self._node) + return [ changectx(self._repo, x) for x in c ] + + def filenode(self, path): + node, flag = self._repo.manifest.find(self.changeset()[0], path) + return node + + def filectx(self, path): + """get a file context from this changeset""" + return filectx(self._repo, path, fileid=self.filenode(path)) + + 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: + yield self.filectx(f, fileid=mf[f]) + +class filectx(object): + """A filecontext object makes access to data related to a particular + filerevision convenient.""" + def __init__(self, repo, path, changeid=None, fileid=None): + """changeid can be a changeset revision, node, or tag. + fileid can be a file revision or node.""" + self._repo = repo + self._path = path + self._id = changeid + self._fileid = fileid + + if self._id: + # if given a changeset id, go ahead and look up the file + self._changeset = changectx(repo, self._id) + node, flag = self._repo.manifest.find(self._changeset[0], path) + self._node = node + self._filelog = self.repo.file(self._path) + elif self._fileid: + # else be lazy + self._filelog = self._repo.file(self._path) + self._filenode = self._filelog.lookup(self._fileid) + self._filerev = self._filelog.rev(self._filenode) + + def changeset(self): + try: + return self._changeset + except AttributeError: + self._changeset = self._repo.changelog.read(self.node()) + return self._changeset + + def filerev(self): return self._filerev + def filenode(self): return self._filenode + def filelog(self): return self._filelog + + def rev(self): return self.changeset().rev() + def node(self): return self.changeset().node() + def user(self): return self.changeset().user() + def date(self): return self.changeset().date() + def files(self): return self.changeset().files() + def description(self): return self.changeset().description() + def manifest(self): return self.changeset().manifest() + + def data(self): return self._filelog.read(self._filenode) + def metadata(self): return self._filelog.readmeta(self._filenode) + def renamed(self): return self._filelog.renamed(self._filenode) + + def parents(self): + # need to fix for renames + p = self._filelog.parents(self._filenode) + return [ filectx(self._repo, self._path, fileid=x) for x in p ] + + def children(self): + # hard for renames + c = self._filelog.children(self._filenode) + return [ filectx(self._repo, self._path, fileid=x) for x in c ] + + def annotate(self): + return self._filelog.annotate(self._filenode)
--- a/mercurial/localrepo.py Tue Jul 04 15:36:05 2006 -0700 +++ b/mercurial/localrepo.py Wed Jul 05 13:28:25 2006 -0500 @@ -9,7 +9,7 @@ from i18n import gettext as _ from demandload import * demandload(globals(), "appendfile changegroup") -demandload(globals(), "changelog dirstate filelog manifest repo") +demandload(globals(), "changelog dirstate filelog manifest repo context") demandload(globals(), "re lock transaction tempfile stat mdiff errno ui") demandload(globals(), "os revlog util") @@ -259,6 +259,14 @@ f = f[1:] return filelog.filelog(self.opener, f, self.revlogversion) + def changectx(self, changeid): + return context.changectx(self, changeid) + + def filectx(self, path, changeid=None, fileid=None): + """changeid can be a changeset revision, node, or tag. + fileid can be a file revision or node.""" + return context.filectx(self, path, changeid, fileid) + def getcwd(self): return self.dirstate.getcwd()
--- a/mercurial/revlog.py Tue Jul 04 15:36:05 2006 -0700 +++ b/mercurial/revlog.py Wed Jul 05 13:28:25 2006 -0500 @@ -743,6 +743,13 @@ def lookup(self, id): """locate a node based on revision number or subset of hex nodeid""" + if id in self.nodemap: + return id + if type(id) == type(0): + rev = id + if rev < 0: rev = self.count() + rev + if rev < 0 or rev >= self.count(): return None + return self.node(rev) try: rev = int(id) if str(rev) != id: raise ValueError