summaryrefslogtreecommitdiff
path: root/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py
diff options
context:
space:
mode:
authorNishanth Amuluru2011-01-11 22:41:51 +0530
committerNishanth Amuluru2011-01-11 22:41:51 +0530
commitb03203c8cb991c16ac8a3d74c8c4078182d0bb48 (patch)
tree7cf13b2deacbfaaec99edb431b83ddd5ea734a52 /eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py
parent0c50203cd9eb94b819883c3110922e873f003138 (diff)
downloadpytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.gz
pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.bz2
pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.zip
removed all the buildout files
Diffstat (limited to 'eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py')
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py610
1 files changed, 0 insertions, 610 deletions
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py
deleted file mode 100644
index 4761dca..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/subrepo.py
+++ /dev/null
@@ -1,610 +0,0 @@
-# subrepo.py - sub-repository handling for Mercurial
-#
-# Copyright 2009-2010 Matt Mackall <mpm@selenic.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
-import stat, subprocess
-from i18n import _
-import config, util, node, error, cmdutil
-hg = None
-
-nullstate = ('', '', 'empty')
-
-def state(ctx, ui):
- """return a state dict, mapping subrepo paths configured in .hgsub
- to tuple: (source from .hgsub, revision from .hgsubstate, kind
- (key in types dict))
- """
- p = config.config()
- def read(f, sections=None, remap=None):
- if f in ctx:
- try:
- data = ctx[f].data()
- except IOError, err:
- if err.errno != errno.ENOENT:
- raise
- # handle missing subrepo spec files as removed
- ui.warn(_("warning: subrepo spec file %s not found\n") % f)
- return
- p.parse(f, data, sections, remap, read)
- else:
- raise util.Abort(_("subrepo spec file %s not found") % f)
-
- if '.hgsub' in ctx:
- read('.hgsub')
-
- for path, src in ui.configitems('subpaths'):
- p.set('subpaths', path, src, ui.configsource('subpaths', path))
-
- rev = {}
- if '.hgsubstate' in ctx:
- try:
- for l in ctx['.hgsubstate'].data().splitlines():
- revision, path = l.split(" ", 1)
- rev[path] = revision
- except IOError, err:
- if err.errno != errno.ENOENT:
- raise
-
- state = {}
- for path, src in p[''].items():
- kind = 'hg'
- if src.startswith('['):
- if ']' not in src:
- raise util.Abort(_('missing ] in subrepo source'))
- kind, src = src.split(']', 1)
- kind = kind[1:]
-
- for pattern, repl in p.items('subpaths'):
- # Turn r'C:\foo\bar' into r'C:\\foo\\bar' since re.sub
- # does a string decode.
- repl = repl.encode('string-escape')
- # However, we still want to allow back references to go
- # through unharmed, so we turn r'\\1' into r'\1'. Again,
- # extra escapes are needed because re.sub string decodes.
- repl = re.sub(r'\\\\([0-9]+)', r'\\\1', repl)
- try:
- src = re.sub(pattern, repl, src, 1)
- except re.error, e:
- raise util.Abort(_("bad subrepository pattern in %s: %s")
- % (p.source('subpaths', pattern), e))
-
- state[path] = (src.strip(), rev.get(path, ''), kind)
-
- return state
-
-def writestate(repo, state):
- """rewrite .hgsubstate in (outer) repo with these subrepo states"""
- repo.wwrite('.hgsubstate',
- ''.join(['%s %s\n' % (state[s][1], s)
- for s in sorted(state)]), '')
-
-def submerge(repo, wctx, mctx, actx):
- """delegated from merge.applyupdates: merging of .hgsubstate file
- in working context, merging context and ancestor context"""
- if mctx == actx: # backwards?
- actx = wctx.p1()
- s1 = wctx.substate
- s2 = mctx.substate
- sa = actx.substate
- sm = {}
-
- repo.ui.debug("subrepo merge %s %s %s\n" % (wctx, mctx, actx))
-
- def debug(s, msg, r=""):
- if r:
- r = "%s:%s:%s" % r
- repo.ui.debug(" subrepo %s: %s %s\n" % (s, msg, r))
-
- for s, l in s1.items():
- a = sa.get(s, nullstate)
- ld = l # local state with possible dirty flag for compares
- if wctx.sub(s).dirty():
- ld = (l[0], l[1] + "+")
- if wctx == actx: # overwrite
- a = ld
-
- if s in s2:
- r = s2[s]
- if ld == r or r == a: # no change or local is newer
- sm[s] = l
- continue
- elif ld == a: # other side changed
- debug(s, "other changed, get", r)
- wctx.sub(s).get(r)
- sm[s] = r
- elif ld[0] != r[0]: # sources differ
- if repo.ui.promptchoice(
- _(' subrepository sources for %s differ\n'
- 'use (l)ocal source (%s) or (r)emote source (%s)?')
- % (s, l[0], r[0]),
- (_('&Local'), _('&Remote')), 0):
- debug(s, "prompt changed, get", r)
- wctx.sub(s).get(r)
- sm[s] = r
- elif ld[1] == a[1]: # local side is unchanged
- debug(s, "other side changed, get", r)
- wctx.sub(s).get(r)
- sm[s] = r
- else:
- debug(s, "both sides changed, merge with", r)
- wctx.sub(s).merge(r)
- sm[s] = l
- elif ld == a: # remote removed, local unchanged
- debug(s, "remote removed, remove")
- wctx.sub(s).remove()
- else:
- if repo.ui.promptchoice(
- _(' local changed subrepository %s which remote removed\n'
- 'use (c)hanged version or (d)elete?') % s,
- (_('&Changed'), _('&Delete')), 0):
- debug(s, "prompt remove")
- wctx.sub(s).remove()
-
- for s, r in s2.items():
- if s in s1:
- continue
- elif s not in sa:
- debug(s, "remote added, get", r)
- mctx.sub(s).get(r)
- sm[s] = r
- elif r != sa[s]:
- if repo.ui.promptchoice(
- _(' remote changed subrepository %s which local removed\n'
- 'use (c)hanged version or (d)elete?') % s,
- (_('&Changed'), _('&Delete')), 0) == 0:
- debug(s, "prompt recreate", r)
- wctx.sub(s).get(r)
- sm[s] = r
-
- # record merged .hgsubstate
- writestate(repo, sm)
-
-def reporelpath(repo):
- """return path to this (sub)repo as seen from outermost repo"""
- parent = repo
- while hasattr(parent, '_subparent'):
- parent = parent._subparent
- return repo.root[len(parent.root)+1:]
-
-def subrelpath(sub):
- """return path to this subrepo as seen from outermost repo"""
- if not hasattr(sub, '_repo'):
- return sub._path
- return reporelpath(sub._repo)
-
-def _abssource(repo, push=False, abort=True):
- """return pull/push path of repo - either based on parent repo .hgsub info
- or on the top repo config. Abort or return None if no source found."""
- if hasattr(repo, '_subparent'):
- source = repo._subsource
- if source.startswith('/') or '://' in source:
- return source
- parent = _abssource(repo._subparent, push, abort=False)
- if parent:
- if '://' in parent:
- if parent[-1] == '/':
- parent = parent[:-1]
- r = urlparse.urlparse(parent + '/' + source)
- r = urlparse.urlunparse((r[0], r[1],
- posixpath.normpath(r[2]),
- r[3], r[4], r[5]))
- return r
- else: # plain file system path
- return posixpath.normpath(os.path.join(parent, repo._subsource))
- else: # recursion reached top repo
- if hasattr(repo, '_subtoppath'):
- return repo._subtoppath
- if push and repo.ui.config('paths', 'default-push'):
- return repo.ui.config('paths', 'default-push')
- if repo.ui.config('paths', 'default'):
- return repo.ui.config('paths', 'default')
- if abort:
- raise util.Abort(_("default path for subrepository %s not found") %
- reporelpath(repo))
-
-def itersubrepos(ctx1, ctx2):
- """find subrepos in ctx1 or ctx2"""
- # Create a (subpath, ctx) mapping where we prefer subpaths from
- # ctx1. The subpaths from ctx2 are important when the .hgsub file
- # has been modified (in ctx2) but not yet committed (in ctx1).
- subpaths = dict.fromkeys(ctx2.substate, ctx2)
- subpaths.update(dict.fromkeys(ctx1.substate, ctx1))
- for subpath, ctx in sorted(subpaths.iteritems()):
- yield subpath, ctx.sub(subpath)
-
-def subrepo(ctx, path):
- """return instance of the right subrepo class for subrepo in path"""
- # subrepo inherently violates our import layering rules
- # because it wants to make repo objects from deep inside the stack
- # so we manually delay the circular imports to not break
- # scripts that don't use our demand-loading
- global hg
- import hg as h
- hg = h
-
- util.path_auditor(ctx._repo.root)(path)
- state = ctx.substate.get(path, nullstate)
- if state[2] not in types:
- raise util.Abort(_('unknown subrepo type %s') % state[2])
- return types[state[2]](ctx, path, state[:2])
-
-# subrepo classes need to implement the following abstract class:
-
-class abstractsubrepo(object):
-
- def dirty(self):
- """returns true if the dirstate of the subrepo does not match
- current stored state
- """
- raise NotImplementedError
-
- def checknested(self, path):
- """check if path is a subrepository within this repository"""
- return False
-
- def commit(self, text, user, date):
- """commit the current changes to the subrepo with the given
- log message. Use given user and date if possible. Return the
- new state of the subrepo.
- """
- raise NotImplementedError
-
- def remove(self):
- """remove the subrepo
-
- (should verify the dirstate is not dirty first)
- """
- raise NotImplementedError
-
- def get(self, state):
- """run whatever commands are needed to put the subrepo into
- this state
- """
- raise NotImplementedError
-
- def merge(self, state):
- """merge currently-saved state with the new state."""
- raise NotImplementedError
-
- def push(self, force):
- """perform whatever action is analogous to 'hg push'
-
- This may be a no-op on some systems.
- """
- raise NotImplementedError
-
- def add(self, ui, match, dryrun, prefix):
- return []
-
- def status(self, rev2, **opts):
- return [], [], [], [], [], [], []
-
- def diff(self, diffopts, node2, match, prefix, **opts):
- pass
-
- def outgoing(self, ui, dest, opts):
- return 1
-
- def incoming(self, ui, source, opts):
- return 1
-
- def files(self):
- """return filename iterator"""
- raise NotImplementedError
-
- def filedata(self, name):
- """return file data"""
- raise NotImplementedError
-
- def fileflags(self, name):
- """return file flags"""
- return ''
-
- def archive(self, archiver, prefix):
- for name in self.files():
- flags = self.fileflags(name)
- mode = 'x' in flags and 0755 or 0644
- symlink = 'l' in flags
- archiver.addfile(os.path.join(prefix, self._path, name),
- mode, symlink, self.filedata(name))
-
-
-class hgsubrepo(abstractsubrepo):
- def __init__(self, ctx, path, state):
- self._path = path
- self._state = state
- r = ctx._repo
- root = r.wjoin(path)
- create = False
- if not os.path.exists(os.path.join(root, '.hg')):
- create = True
- util.makedirs(root)
- self._repo = hg.repository(r.ui, root, create=create)
- self._repo._subparent = r
- self._repo._subsource = state[0]
-
- if create:
- fp = self._repo.opener("hgrc", "w", text=True)
- fp.write('[paths]\n')
-
- def addpathconfig(key, value):
- if value:
- fp.write('%s = %s\n' % (key, value))
- self._repo.ui.setconfig('paths', key, value)
-
- defpath = _abssource(self._repo, abort=False)
- defpushpath = _abssource(self._repo, True, abort=False)
- addpathconfig('default', defpath)
- if defpath != defpushpath:
- addpathconfig('default-push', defpushpath)
- fp.close()
-
- def add(self, ui, match, dryrun, prefix):
- return cmdutil.add(ui, self._repo, match, dryrun, True,
- os.path.join(prefix, self._path))
-
- def status(self, rev2, **opts):
- try:
- rev1 = self._state[1]
- ctx1 = self._repo[rev1]
- ctx2 = self._repo[rev2]
- return self._repo.status(ctx1, ctx2, **opts)
- except error.RepoLookupError, inst:
- self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
- % (inst, subrelpath(self)))
- return [], [], [], [], [], [], []
-
- def diff(self, diffopts, node2, match, prefix, **opts):
- try:
- node1 = node.bin(self._state[1])
- # We currently expect node2 to come from substate and be
- # in hex format
- if node2 is not None:
- node2 = node.bin(node2)
- cmdutil.diffordiffstat(self._repo.ui, self._repo, diffopts,
- node1, node2, match,
- prefix=os.path.join(prefix, self._path),
- listsubrepos=True, **opts)
- except error.RepoLookupError, inst:
- self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
- % (inst, subrelpath(self)))
-
- def archive(self, archiver, prefix):
- abstractsubrepo.archive(self, archiver, prefix)
-
- rev = self._state[1]
- ctx = self._repo[rev]
- for subpath in ctx.substate:
- s = subrepo(ctx, subpath)
- s.archive(archiver, os.path.join(prefix, self._path))
-
- def dirty(self):
- r = self._state[1]
- if r == '':
- return True
- w = self._repo[None]
- if w.p1() != self._repo[r]: # version checked out change
- return True
- return w.dirty() # working directory changed
-
- def checknested(self, path):
- return self._repo._checknested(self._repo.wjoin(path))
-
- def commit(self, text, user, date):
- self._repo.ui.debug("committing subrepo %s\n" % subrelpath(self))
- n = self._repo.commit(text, user, date)
- if not n:
- return self._repo['.'].hex() # different version checked out
- return node.hex(n)
-
- def remove(self):
- # we can't fully delete the repository as it may contain
- # local-only history
- self._repo.ui.note(_('removing subrepo %s\n') % subrelpath(self))
- hg.clean(self._repo, node.nullid, False)
-
- def _get(self, state):
- source, revision, kind = state
- try:
- self._repo.lookup(revision)
- except error.RepoError:
- self._repo._subsource = source
- srcurl = _abssource(self._repo)
- self._repo.ui.status(_('pulling subrepo %s from %s\n')
- % (subrelpath(self), srcurl))
- other = hg.repository(self._repo.ui, srcurl)
- self._repo.pull(other)
-
- def get(self, state):
- self._get(state)
- source, revision, kind = state
- self._repo.ui.debug("getting subrepo %s\n" % self._path)
- hg.clean(self._repo, revision, False)
-
- def merge(self, state):
- self._get(state)
- cur = self._repo['.']
- dst = self._repo[state[1]]
- anc = dst.ancestor(cur)
- if anc == cur:
- self._repo.ui.debug("updating subrepo %s\n" % subrelpath(self))
- hg.update(self._repo, state[1])
- elif anc == dst:
- self._repo.ui.debug("skipping subrepo %s\n" % subrelpath(self))
- else:
- self._repo.ui.debug("merging subrepo %s\n" % subrelpath(self))
- hg.merge(self._repo, state[1], remind=False)
-
- def push(self, force):
- # push subrepos depth-first for coherent ordering
- c = self._repo['']
- subs = c.substate # only repos that are committed
- for s in sorted(subs):
- if not c.sub(s).push(force):
- return False
-
- dsturl = _abssource(self._repo, True)
- self._repo.ui.status(_('pushing subrepo %s to %s\n') %
- (subrelpath(self), dsturl))
- other = hg.repository(self._repo.ui, dsturl)
- return self._repo.push(other, force)
-
- def outgoing(self, ui, dest, opts):
- return hg.outgoing(ui, self._repo, _abssource(self._repo, True), opts)
-
- def incoming(self, ui, source, opts):
- return hg.incoming(ui, self._repo, _abssource(self._repo, False), opts)
-
- def files(self):
- rev = self._state[1]
- ctx = self._repo[rev]
- return ctx.manifest()
-
- def filedata(self, name):
- rev = self._state[1]
- return self._repo[rev][name].data()
-
- def fileflags(self, name):
- rev = self._state[1]
- ctx = self._repo[rev]
- return ctx.flags(name)
-
-
-class svnsubrepo(abstractsubrepo):
- def __init__(self, ctx, path, state):
- self._path = path
- self._state = state
- self._ctx = ctx
- self._ui = ctx._repo.ui
-
- def _svncommand(self, commands, filename=''):
- path = os.path.join(self._ctx._repo.origroot, self._path, filename)
- cmd = ['svn'] + commands + [path]
- cmd = [util.shellquote(arg) for arg in cmd]
- cmd = util.quotecommand(' '.join(cmd))
- env = dict(os.environ)
- # Avoid localized output, preserve current locale for everything else.
- env['LC_MESSAGES'] = 'C'
- p = subprocess.Popen(cmd, shell=True, bufsize=-1,
- close_fds=util.closefds,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- universal_newlines=True, env=env)
- stdout, stderr = p.communicate()
- stderr = stderr.strip()
- if stderr:
- raise util.Abort(stderr)
- return stdout
-
- def _wcrev(self):
- output = self._svncommand(['info', '--xml'])
- doc = xml.dom.minidom.parseString(output)
- entries = doc.getElementsByTagName('entry')
- if not entries:
- return '0'
- return str(entries[0].getAttribute('revision')) or '0'
-
- def _wcchanged(self):
- """Return (changes, extchanges) where changes is True
- if the working directory was changed, and extchanges is
- True if any of these changes concern an external entry.
- """
- output = self._svncommand(['status', '--xml'])
- externals, changes = [], []
- doc = xml.dom.minidom.parseString(output)
- for e in doc.getElementsByTagName('entry'):
- s = e.getElementsByTagName('wc-status')
- if not s:
- continue
- item = s[0].getAttribute('item')
- props = s[0].getAttribute('props')
- path = e.getAttribute('path')
- if item == 'external':
- externals.append(path)
- if (item not in ('', 'normal', 'unversioned', 'external')
- or props not in ('', 'none')):
- changes.append(path)
- for path in changes:
- for ext in externals:
- if path == ext or path.startswith(ext + os.sep):
- return True, True
- return bool(changes), False
-
- def dirty(self):
- if self._wcrev() == self._state[1] and not self._wcchanged()[0]:
- return False
- return True
-
- def commit(self, text, user, date):
- # user and date are out of our hands since svn is centralized
- changed, extchanged = self._wcchanged()
- if not changed:
- return self._wcrev()
- if extchanged:
- # Do not try to commit externals
- raise util.Abort(_('cannot commit svn externals'))
- commitinfo = self._svncommand(['commit', '-m', text])
- self._ui.status(commitinfo)
- newrev = re.search('Committed revision ([0-9]+).', commitinfo)
- if not newrev:
- raise util.Abort(commitinfo.splitlines()[-1])
- newrev = newrev.groups()[0]
- self._ui.status(self._svncommand(['update', '-r', newrev]))
- return newrev
-
- def remove(self):
- if self.dirty():
- self._ui.warn(_('not removing repo %s because '
- 'it has changes.\n' % self._path))
- return
- self._ui.note(_('removing subrepo %s\n') % self._path)
-
- def onerror(function, path, excinfo):
- if function is not os.remove:
- raise
- # read-only files cannot be unlinked under Windows
- s = os.stat(path)
- if (s.st_mode & stat.S_IWRITE) != 0:
- raise
- os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
- os.remove(path)
-
- path = self._ctx._repo.wjoin(self._path)
- shutil.rmtree(path, onerror=onerror)
- try:
- os.removedirs(os.path.dirname(path))
- except OSError:
- pass
-
- def get(self, state):
- status = self._svncommand(['checkout', state[0], '--revision', state[1]])
- if not re.search('Checked out revision [0-9]+.', status):
- raise util.Abort(status.splitlines()[-1])
- self._ui.status(status)
-
- def merge(self, state):
- old = int(self._state[1])
- new = int(state[1])
- if new > old:
- self.get(state)
-
- def push(self, force):
- # push is a no-op for SVN
- return True
-
- def files(self):
- output = self._svncommand(['list'])
- # This works because svn forbids \n in filenames.
- return output.splitlines()
-
- def filedata(self, name):
- return self._svncommand(['cat'], name)
-
-
-types = {
- 'hg': hgsubrepo,
- 'svn': svnsubrepo,
- }