summaryrefslogtreecommitdiff
path: root/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext
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/hgext
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/hgext')
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.py1
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.pyobin186 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.py250
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.pyobin8875 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.py579
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.pyobin21456 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.py441
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.pyobin18525 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.py45
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.pyobin1514 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.py198
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.pyobin9040 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.py319
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.pyobin11558 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.py321
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.pyobin14008 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.py260
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.pyobin9581 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.py389
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.pyobin20100 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.py434
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.pyobin16933 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.py271
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.pyobin9466 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.py847
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.pyobin21195 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.py200
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.pyobin8694 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.py365
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.pyobin11449 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.py170
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.pyobin7015 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.py338
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.pyobin12415 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.py376
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.pyobin16042 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.py227
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.pyobin7808 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.py202
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.pyobin7333 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.py1168
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.pyobin39371 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.py128
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.pyobin5744 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.py272
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.pyobin10766 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.py325
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.pyobin10985 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.py152
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.pyobin5046 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.py288
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.pyobin10444 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.py337
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.pyobin12442 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.py251
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.pyobin10391 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.py348
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.pyobin11815 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.py61
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.pyobin2545 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.py61
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.pyobin2358 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.py81
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.pyobin2746 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.py649
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.pyobin29160 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.py3211
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.pyobin112419 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.py316
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.pyobin11753 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.py113
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.pyobin4114 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.py96
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.pyobin2626 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.py553
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.pyobin20701 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.py206
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.pyobin8302 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.py111
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.pyobin3694 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.py577
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.pyobin20920 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.py569
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.pyobin22073 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.py180
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.pyobin6226 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.py84
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.pyobin3984 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.py38
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.pyobin1595 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.py630
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.pyobin23926 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.py159
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.pyobin5770 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.py170
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.pyobin7010 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.py1582
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.pyobin66077 -> 0 bytes
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.py173
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.pyobin7506 -> 0 bytes
100 files changed, 0 insertions, 19122 deletions
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.py
deleted file mode 100644
index fdffa2a..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# placeholder
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.pyo
deleted file mode 100644
index 96afc1a..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/__init__.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.py
deleted file mode 100644
index a50fa72..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# acl.py - changeset access control for mercurial
-#
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''hooks for controlling repository access
-
-This hook makes it possible to allow or deny write access to given
-branches and paths of a repository when receiving incoming changesets
-via pretxnchangegroup and pretxncommit.
-
-The authorization is matched based on the local user name on the
-system where the hook runs, and not the committer of the original
-changeset (since the latter is merely informative).
-
-The acl hook is best used along with a restricted shell like hgsh,
-preventing authenticating users from doing anything other than pushing
-or pulling. The hook is not safe to use if users have interactive
-shell access, as they can then disable the hook. Nor is it safe if
-remote users share an account, because then there is no way to
-distinguish them.
-
-The order in which access checks are performed is:
-
-1) Deny list for branches (section ``acl.deny.branches``)
-2) Allow list for branches (section ``acl.allow.branches``)
-3) Deny list for paths (section ``acl.deny``)
-4) Allow list for paths (section ``acl.allow``)
-
-The allow and deny sections take key-value pairs.
-
-Branch-based Access Control
-...........................
-
-Use the ``acl.deny.branches`` and ``acl.allow.branches`` sections to
-have branch-based access control. Keys in these sections can be
-either:
-
-- a branch name, or
-- an asterisk, to match any branch;
-
-The corresponding values can be either:
-
-- a comma-separated list containing users and groups, or
-- an asterisk, to match anyone;
-
-Path-based Access Control
-.........................
-
-Use the ``acl.deny`` and ``acl.allow`` sections to have path-based
-access control. Keys in these sections accept a subtree pattern (with
-a glob syntax by default). The corresponding values follow the same
-syntax as the other sections above.
-
-Groups
-......
-
-Group names must be prefixed with an ``@`` symbol. Specifying a group
-name has the same effect as specifying all the users in that group.
-
-You can define group members in the ``acl.groups`` section.
-If a group name is not defined there, and Mercurial is running under
-a Unix-like system, the list of users will be taken from the OS.
-Otherwise, an exception will be raised.
-
-Example Configuration
-.....................
-
-::
-
- [hooks]
-
- # Use this if you want to check access restrictions at commit time
- pretxncommit.acl = python:hgext.acl.hook
-
- # Use this if you want to check access restrictions for pull, push,
- # bundle and serve.
- pretxnchangegroup.acl = python:hgext.acl.hook
-
- [acl]
- # Allow or deny access for incoming changes only if their source is
- # listed here, let them pass otherwise. Source is "serve" for all
- # remote access (http or ssh), "push", "pull" or "bundle" when the
- # related commands are run locally.
- # Default: serve
- sources = serve
-
- [acl.deny.branches]
-
- # Everyone is denied to the frozen branch:
- frozen-branch = *
-
- # A bad user is denied on all branches:
- * = bad-user
-
- [acl.allow.branches]
-
- # A few users are allowed on branch-a:
- branch-a = user-1, user-2, user-3
-
- # Only one user is allowed on branch-b:
- branch-b = user-1
-
- # The super user is allowed on any branch:
- * = super-user
-
- # Everyone is allowed on branch-for-tests:
- branch-for-tests = *
-
- [acl.deny]
- # This list is checked first. If a match is found, acl.allow is not
- # checked. All users are granted access if acl.deny is not present.
- # Format for both lists: glob pattern = user, ..., @group, ...
-
- # To match everyone, use an asterisk for the user:
- # my/glob/pattern = *
-
- # user6 will not have write access to any file:
- ** = user6
-
- # Group "hg-denied" will not have write access to any file:
- ** = @hg-denied
-
- # Nobody will be able to change "DONT-TOUCH-THIS.txt", despite
- # everyone being able to change all other files. See below.
- src/main/resources/DONT-TOUCH-THIS.txt = *
-
- [acl.allow]
- # if acl.allow is not present, all users are allowed by default
- # empty acl.allow = no users allowed
-
- # User "doc_writer" has write access to any file under the "docs"
- # folder:
- docs/** = doc_writer
-
- # User "jack" and group "designers" have write access to any file
- # under the "images" folder:
- images/** = jack, @designers
-
- # Everyone (except for "user6" - see acl.deny above) will have write
- # access to any file under the "resources" folder (except for 1
- # file. See acl.deny):
- src/main/resources/** = *
-
- .hgtags = release_engineer
-
-'''
-
-from mercurial.i18n import _
-from mercurial import util, match
-import getpass, urllib
-
-def _getusers(ui, group):
-
- # First, try to use group definition from section [acl.groups]
- hgrcusers = ui.configlist('acl.groups', group)
- if hgrcusers:
- return hgrcusers
-
- ui.debug('acl: "%s" not defined in [acl.groups]\n' % group)
- # If no users found in group definition, get users from OS-level group
- try:
- return util.groupmembers(group)
- except KeyError:
- raise util.Abort(_("group '%s' is undefined") % group)
-
-def _usermatch(ui, user, usersorgroups):
-
- if usersorgroups == '*':
- return True
-
- for ug in usersorgroups.replace(',', ' ').split():
- if user == ug or ug.find('@') == 0 and user in _getusers(ui, ug[1:]):
- return True
-
- return False
-
-def buildmatch(ui, repo, user, key):
- '''return tuple of (match function, list enabled).'''
- if not ui.has_section(key):
- ui.debug('acl: %s not enabled\n' % key)
- return None
-
- pats = [pat for pat, users in ui.configitems(key)
- if _usermatch(ui, user, users)]
- ui.debug('acl: %s enabled, %d entries for user %s\n' %
- (key, len(pats), user))
-
- if not repo:
- if pats:
- return lambda b: '*' in pats or b in pats
- return lambda b: False
-
- if pats:
- return match.match(repo.root, '', pats)
- return match.exact(repo.root, '', [])
-
-
-def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
- if hooktype not in ['pretxnchangegroup', 'pretxncommit']:
- raise util.Abort(_('config error - hook type "%s" cannot stop '
- 'incoming changesets nor commits') % hooktype)
- if (hooktype == 'pretxnchangegroup' and
- source not in ui.config('acl', 'sources', 'serve').split()):
- ui.debug('acl: changes have source "%s" - skipping\n' % source)
- return
-
- user = None
- if source == 'serve' and 'url' in kwargs:
- url = kwargs['url'].split(':')
- if url[0] == 'remote' and url[1].startswith('http'):
- user = urllib.unquote(url[3])
-
- if user is None:
- user = getpass.getuser()
-
- cfg = ui.config('acl', 'config')
- if cfg:
- ui.readconfig(cfg, sections = ['acl.groups', 'acl.allow.branches',
- 'acl.deny.branches', 'acl.allow', 'acl.deny'])
-
- allowbranches = buildmatch(ui, None, user, 'acl.allow.branches')
- denybranches = buildmatch(ui, None, user, 'acl.deny.branches')
- allow = buildmatch(ui, repo, user, 'acl.allow')
- deny = buildmatch(ui, repo, user, 'acl.deny')
-
- for rev in xrange(repo[node], len(repo)):
- ctx = repo[rev]
- branch = ctx.branch()
- if denybranches and denybranches(branch):
- raise util.Abort(_('acl: user "%s" denied on branch "%s"'
- ' (changeset "%s")')
- % (user, branch, ctx))
- if allowbranches and not allowbranches(branch):
- raise util.Abort(_('acl: user "%s" not allowed on branch "%s"'
- ' (changeset "%s")')
- % (user, branch, ctx))
- ui.debug('acl: branch access granted: "%s" on branch "%s"\n'
- % (ctx, branch))
-
- for f in ctx.files():
- if deny and deny(f):
- ui.debug('acl: user %s denied on %s\n' % (user, f))
- raise util.Abort(_('acl: access denied for changeset %s') % ctx)
- if allow and not allow(f):
- ui.debug('acl: user %s not allowed on %s\n' % (user, f))
- raise util.Abort(_('acl: access denied for changeset %s') % ctx)
- ui.debug('acl: allowing changeset %s\n' % ctx)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.pyo
deleted file mode 100644
index 8001bf2..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/acl.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.py
deleted file mode 100644
index 1ebbc7a..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.py
+++ /dev/null
@@ -1,579 +0,0 @@
-# Mercurial extension to provide the 'hg bookmark' command
-#
-# Copyright 2008 David Soria Parra <dsp@php.net>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''track a line of development with movable markers
-
-Bookmarks are local movable markers to changesets. Every bookmark
-points to a changeset identified by its hash. If you commit a
-changeset that is based on a changeset that has a bookmark on it, the
-bookmark shifts to the new changeset.
-
-It is possible to use bookmark names in every revision lookup (e.g.
-:hg:`merge`, :hg:`update`).
-
-By default, when several bookmarks point to the same changeset, they
-will all move forward together. It is possible to obtain a more
-git-like experience by adding the following configuration option to
-your configuration file::
-
- [bookmarks]
- track.current = True
-
-This will cause Mercurial to track the bookmark that you are currently
-using, and only update it. This is similar to git's approach to
-branching.
-'''
-
-from mercurial.i18n import _
-from mercurial.node import nullid, nullrev, bin, hex, short
-from mercurial import util, commands, repair, extensions, pushkey, hg, url
-from mercurial import revset
-import os
-
-def write(repo):
- '''Write bookmarks
-
- Write the given bookmark => hash dictionary to the .hg/bookmarks file
- in a format equal to those of localtags.
-
- We also store a backup of the previous state in undo.bookmarks that
- can be copied back on rollback.
- '''
- refs = repo._bookmarks
-
- try:
- bms = repo.opener('bookmarks').read()
- except IOError:
- bms = None
- if bms is not None:
- repo.opener('undo.bookmarks', 'w').write(bms)
-
- if repo._bookmarkcurrent not in refs:
- setcurrent(repo, None)
- wlock = repo.wlock()
- try:
- file = repo.opener('bookmarks', 'w', atomictemp=True)
- for refspec, node in refs.iteritems():
- file.write("%s %s\n" % (hex(node), refspec))
- file.rename()
-
- # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
- try:
- os.utime(repo.sjoin('00changelog.i'), None)
- except OSError:
- pass
-
- finally:
- wlock.release()
-
-def setcurrent(repo, mark):
- '''Set the name of the bookmark that we are currently on
-
- Set the name of the bookmark that we are on (hg update <bookmark>).
- The name is recorded in .hg/bookmarks.current
- '''
- current = repo._bookmarkcurrent
- if current == mark:
- return
-
- refs = repo._bookmarks
-
- # do not update if we do update to a rev equal to the current bookmark
- if (mark and mark not in refs and
- current and refs[current] == repo.changectx('.').node()):
- return
- if mark not in refs:
- mark = ''
- wlock = repo.wlock()
- try:
- file = repo.opener('bookmarks.current', 'w', atomictemp=True)
- file.write(mark)
- file.rename()
- finally:
- wlock.release()
- repo._bookmarkcurrent = mark
-
-def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
- '''track a line of development with movable markers
-
- Bookmarks are pointers to certain commits that move when
- committing. Bookmarks are local. They can be renamed, copied and
- deleted. It is possible to use bookmark names in :hg:`merge` and
- :hg:`update` to merge and update respectively to a given bookmark.
-
- You can use :hg:`bookmark NAME` to set a bookmark on the working
- directory's parent revision with the given name. If you specify
- a revision using -r REV (where REV may be an existing bookmark),
- the bookmark is assigned to that revision.
-
- Bookmarks can be pushed and pulled between repositories (see :hg:`help
- push` and :hg:`help pull`). This requires the bookmark extension to be
- enabled for both the local and remote repositories.
- '''
- hexfn = ui.debugflag and hex or short
- marks = repo._bookmarks
- cur = repo.changectx('.').node()
-
- if rename:
- if rename not in marks:
- raise util.Abort(_("a bookmark of this name does not exist"))
- if mark in marks and not force:
- raise util.Abort(_("a bookmark of the same name already exists"))
- if mark is None:
- raise util.Abort(_("new bookmark name required"))
- marks[mark] = marks[rename]
- del marks[rename]
- if repo._bookmarkcurrent == rename:
- setcurrent(repo, mark)
- write(repo)
- return
-
- if delete:
- if mark is None:
- raise util.Abort(_("bookmark name required"))
- if mark not in marks:
- raise util.Abort(_("a bookmark of this name does not exist"))
- if mark == repo._bookmarkcurrent:
- setcurrent(repo, None)
- del marks[mark]
- write(repo)
- return
-
- if mark != None:
- if "\n" in mark:
- raise util.Abort(_("bookmark name cannot contain newlines"))
- mark = mark.strip()
- if not mark:
- raise util.Abort(_("bookmark names cannot consist entirely of "
- "whitespace"))
- if mark in marks and not force:
- raise util.Abort(_("a bookmark of the same name already exists"))
- if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
- and not force):
- raise util.Abort(
- _("a bookmark cannot have the name of an existing branch"))
- if rev:
- marks[mark] = repo.lookup(rev)
- else:
- marks[mark] = repo.changectx('.').node()
- setcurrent(repo, mark)
- write(repo)
- return
-
- if mark is None:
- if rev:
- raise util.Abort(_("bookmark name required"))
- if len(marks) == 0:
- ui.status(_("no bookmarks set\n"))
- else:
- for bmark, n in marks.iteritems():
- if ui.configbool('bookmarks', 'track.current'):
- current = repo._bookmarkcurrent
- if bmark == current and n == cur:
- prefix, label = '*', 'bookmarks.current'
- else:
- prefix, label = ' ', ''
- else:
- if n == cur:
- prefix, label = '*', 'bookmarks.current'
- else:
- prefix, label = ' ', ''
-
- if ui.quiet:
- ui.write("%s\n" % bmark, label=label)
- else:
- ui.write(" %s %-25s %d:%s\n" % (
- prefix, bmark, repo.changelog.rev(n), hexfn(n)),
- label=label)
- return
-
-def _revstostrip(changelog, node):
- srev = changelog.rev(node)
- tostrip = [srev]
- saveheads = []
- for r in xrange(srev, len(changelog)):
- parents = changelog.parentrevs(r)
- if parents[0] in tostrip or parents[1] in tostrip:
- tostrip.append(r)
- if parents[1] != nullrev:
- for p in parents:
- if p not in tostrip and p > srev:
- saveheads.append(p)
- return [r for r in tostrip if r not in saveheads]
-
-def strip(oldstrip, ui, repo, node, backup="all"):
- """Strip bookmarks if revisions are stripped using
- the mercurial.strip method. This usually happens during
- qpush and qpop"""
- revisions = _revstostrip(repo.changelog, node)
- marks = repo._bookmarks
- update = []
- for mark, n in marks.iteritems():
- if repo.changelog.rev(n) in revisions:
- update.append(mark)
- oldstrip(ui, repo, node, backup)
- if len(update) > 0:
- for m in update:
- marks[m] = repo.changectx('.').node()
- write(repo)
-
-def reposetup(ui, repo):
- if not repo.local():
- return
-
- class bookmark_repo(repo.__class__):
-
- @util.propertycache
- def _bookmarks(self):
- '''Parse .hg/bookmarks file and return a dictionary
-
- Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
- in the .hg/bookmarks file.
- Read the file and return a (name=>nodeid) dictionary
- '''
- try:
- bookmarks = {}
- for line in self.opener('bookmarks'):
- sha, refspec = line.strip().split(' ', 1)
- bookmarks[refspec] = self.changelog.lookup(sha)
- except:
- pass
- return bookmarks
-
- @util.propertycache
- def _bookmarkcurrent(self):
- '''Get the current bookmark
-
- If we use gittishsh branches we have a current bookmark that
- we are on. This function returns the name of the bookmark. It
- is stored in .hg/bookmarks.current
- '''
- mark = None
- if os.path.exists(self.join('bookmarks.current')):
- file = self.opener('bookmarks.current')
- # No readline() in posixfile_nt, reading everything is cheap
- mark = (file.readlines() or [''])[0]
- if mark == '':
- mark = None
- file.close()
- return mark
-
- def rollback(self, *args):
- if os.path.exists(self.join('undo.bookmarks')):
- util.rename(self.join('undo.bookmarks'), self.join('bookmarks'))
- return super(bookmark_repo, self).rollback(*args)
-
- def lookup(self, key):
- if key in self._bookmarks:
- key = self._bookmarks[key]
- return super(bookmark_repo, self).lookup(key)
-
- def _bookmarksupdate(self, parents, node):
- marks = self._bookmarks
- update = False
- if ui.configbool('bookmarks', 'track.current'):
- mark = self._bookmarkcurrent
- if mark and marks[mark] in parents:
- marks[mark] = node
- update = True
- else:
- for mark, n in marks.items():
- if n in parents:
- marks[mark] = node
- update = True
- if update:
- write(self)
-
- def commitctx(self, ctx, error=False):
- """Add a revision to the repository and
- move the bookmark"""
- wlock = self.wlock() # do both commit and bookmark with lock held
- try:
- node = super(bookmark_repo, self).commitctx(ctx, error)
- if node is None:
- return None
- parents = self.changelog.parents(node)
- if parents[1] == nullid:
- parents = (parents[0],)
-
- self._bookmarksupdate(parents, node)
- return node
- finally:
- wlock.release()
-
- def pull(self, remote, heads=None, force=False):
- result = super(bookmark_repo, self).pull(remote, heads, force)
-
- self.ui.debug("checking for updated bookmarks\n")
- rb = remote.listkeys('bookmarks')
- changed = False
- for k in rb.keys():
- if k in self._bookmarks:
- nr, nl = rb[k], self._bookmarks[k]
- if nr in self:
- cr = self[nr]
- cl = self[nl]
- if cl.rev() >= cr.rev():
- continue
- if cr in cl.descendants():
- self._bookmarks[k] = cr.node()
- changed = True
- self.ui.status(_("updating bookmark %s\n") % k)
- else:
- self.ui.warn(_("not updating divergent"
- " bookmark %s\n") % k)
- if changed:
- write(repo)
-
- return result
-
- def push(self, remote, force=False, revs=None, newbranch=False):
- result = super(bookmark_repo, self).push(remote, force, revs,
- newbranch)
-
- self.ui.debug("checking for updated bookmarks\n")
- rb = remote.listkeys('bookmarks')
- for k in rb.keys():
- if k in self._bookmarks:
- nr, nl = rb[k], self._bookmarks[k]
- if nr in self:
- cr = self[nr]
- cl = self[nl]
- if cl in cr.descendants():
- r = remote.pushkey('bookmarks', k, nr, nl)
- if r:
- self.ui.status(_("updating bookmark %s\n") % k)
- else:
- self.ui.warn(_('updating bookmark %s'
- ' failed!\n') % k)
-
- return result
-
- def addchangegroup(self, *args, **kwargs):
- parents = self.dirstate.parents()
-
- result = super(bookmark_repo, self).addchangegroup(*args, **kwargs)
- if result > 1:
- # We have more heads than before
- return result
- node = self.changelog.tip()
-
- self._bookmarksupdate(parents, node)
- return result
-
- def _findtags(self):
- """Merge bookmarks with normal tags"""
- (tags, tagtypes) = super(bookmark_repo, self)._findtags()
- tags.update(self._bookmarks)
- return (tags, tagtypes)
-
- if hasattr(repo, 'invalidate'):
- def invalidate(self):
- super(bookmark_repo, self).invalidate()
- for attr in ('_bookmarks', '_bookmarkcurrent'):
- if attr in self.__dict__:
- delattr(self, attr)
-
- repo.__class__ = bookmark_repo
-
-def listbookmarks(repo):
- # We may try to list bookmarks on a repo type that does not
- # support it (e.g., statichttprepository).
- if not hasattr(repo, '_bookmarks'):
- return {}
-
- d = {}
- for k, v in repo._bookmarks.iteritems():
- d[k] = hex(v)
- return d
-
-def pushbookmark(repo, key, old, new):
- w = repo.wlock()
- try:
- marks = repo._bookmarks
- if hex(marks.get(key, '')) != old:
- return False
- if new == '':
- del marks[key]
- else:
- if new not in repo:
- return False
- marks[key] = repo[new].node()
- write(repo)
- return True
- finally:
- w.release()
-
-def pull(oldpull, ui, repo, source="default", **opts):
- # translate bookmark args to rev args for actual pull
- if opts.get('bookmark'):
- # this is an unpleasant hack as pull will do this internally
- source, branches = hg.parseurl(ui.expandpath(source),
- opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), source)
- rb = other.listkeys('bookmarks')
-
- for b in opts['bookmark']:
- if b not in rb:
- raise util.Abort(_('remote bookmark %s not found!') % b)
- opts.setdefault('rev', []).append(b)
-
- result = oldpull(ui, repo, source, **opts)
-
- # update specified bookmarks
- if opts.get('bookmark'):
- for b in opts['bookmark']:
- # explicit pull overrides local bookmark if any
- ui.status(_("importing bookmark %s\n") % b)
- repo._bookmarks[b] = repo[rb[b]].node()
- write(repo)
-
- return result
-
-def push(oldpush, ui, repo, dest=None, **opts):
- dopush = True
- if opts.get('bookmark'):
- dopush = False
- for b in opts['bookmark']:
- if b in repo._bookmarks:
- dopush = True
- opts.setdefault('rev', []).append(b)
-
- result = 0
- if dopush:
- result = oldpush(ui, repo, dest, **opts)
-
- if opts.get('bookmark'):
- # this is an unpleasant hack as push will do this internally
- dest = ui.expandpath(dest or 'default-push', dest or 'default')
- dest, branches = hg.parseurl(dest, opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), dest)
- rb = other.listkeys('bookmarks')
- for b in opts['bookmark']:
- # explicit push overrides remote bookmark if any
- if b in repo._bookmarks:
- ui.status(_("exporting bookmark %s\n") % b)
- new = repo[b].hex()
- elif b in rb:
- ui.status(_("deleting remote bookmark %s\n") % b)
- new = '' # delete
- else:
- ui.warn(_('bookmark %s does not exist on the local '
- 'or remote repository!\n') % b)
- return 2
- old = rb.get(b, '')
- r = other.pushkey('bookmarks', b, old, new)
- if not r:
- ui.warn(_('updating bookmark %s failed!\n') % b)
- if not result:
- result = 2
-
- return result
-
-def diffbookmarks(ui, repo, remote):
- ui.status(_("searching for changed bookmarks\n"))
-
- lmarks = repo.listkeys('bookmarks')
- rmarks = remote.listkeys('bookmarks')
-
- diff = sorted(set(rmarks) - set(lmarks))
- for k in diff:
- ui.write(" %-25s %s\n" % (k, rmarks[k][:12]))
-
- if len(diff) <= 0:
- ui.status(_("no changed bookmarks found\n"))
- return 1
- return 0
-
-def incoming(oldincoming, ui, repo, source="default", **opts):
- if opts.get('bookmarks'):
- source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), source)
- ui.status(_('comparing with %s\n') % url.hidepassword(source))
- return diffbookmarks(ui, repo, other)
- else:
- return oldincoming(ui, repo, source, **opts)
-
-def outgoing(oldoutgoing, ui, repo, dest=None, **opts):
- if opts.get('bookmarks'):
- dest = ui.expandpath(dest or 'default-push', dest or 'default')
- dest, branches = hg.parseurl(dest, opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), dest)
- ui.status(_('comparing with %s\n') % url.hidepassword(dest))
- return diffbookmarks(ui, other, repo)
- else:
- return oldoutgoing(ui, repo, dest, **opts)
-
-def uisetup(ui):
- extensions.wrapfunction(repair, "strip", strip)
- if ui.configbool('bookmarks', 'track.current'):
- extensions.wrapcommand(commands.table, 'update', updatecurbookmark)
-
- entry = extensions.wrapcommand(commands.table, 'pull', pull)
- entry[1].append(('B', 'bookmark', [],
- _("bookmark to import"),
- _('BOOKMARK')))
- entry = extensions.wrapcommand(commands.table, 'push', push)
- entry[1].append(('B', 'bookmark', [],
- _("bookmark to export"),
- _('BOOKMARK')))
- entry = extensions.wrapcommand(commands.table, 'incoming', incoming)
- entry[1].append(('B', 'bookmarks', False,
- _("compare bookmark")))
- entry = extensions.wrapcommand(commands.table, 'outgoing', outgoing)
- entry[1].append(('B', 'bookmarks', False,
- _("compare bookmark")))
-
- pushkey.register('bookmarks', pushbookmark, listbookmarks)
-
-def updatecurbookmark(orig, ui, repo, *args, **opts):
- '''Set the current bookmark
-
- If the user updates to a bookmark we update the .hg/bookmarks.current
- file.
- '''
- res = orig(ui, repo, *args, **opts)
- rev = opts['rev']
- if not rev and len(args) > 0:
- rev = args[0]
- setcurrent(repo, rev)
- return res
-
-def bmrevset(repo, subset, x):
- """``bookmark([name])``
- The named bookmark or all bookmarks.
- """
- # i18n: "bookmark" is a keyword
- args = revset.getargs(x, 0, 1, _('bookmark takes one or no arguments'))
- if args:
- bm = revset.getstring(args[0],
- # i18n: "bookmark" is a keyword
- _('the argument to bookmark must be a string'))
- bmrev = listbookmarks(repo).get(bm, None)
- if bmrev:
- bmrev = repo.changelog.rev(bin(bmrev))
- return [r for r in subset if r == bmrev]
- bms = set([repo.changelog.rev(bin(r)) for r in listbookmarks(repo).values()])
- return [r for r in subset if r in bms]
-
-def extsetup(ui):
- revset.symbols['bookmark'] = bmrevset
-
-cmdtable = {
- "bookmarks":
- (bookmark,
- [('f', 'force', False, _('force')),
- ('r', 'rev', '', _('revision'), _('REV')),
- ('d', 'delete', False, _('delete a given bookmark')),
- ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
- _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
-}
-
-colortable = {'bookmarks.current': 'green'}
-
-# tell hggettext to extract docstrings from these functions:
-i18nfunctions = [bmrevset]
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.pyo
deleted file mode 100644
index 9cad1f2..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bookmarks.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.py
deleted file mode 100644
index de72e91..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.py
+++ /dev/null
@@ -1,441 +0,0 @@
-# bugzilla.py - bugzilla integration for mercurial
-#
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''hooks for integrating with the Bugzilla bug tracker
-
-This hook extension adds comments on bugs in Bugzilla when changesets
-that refer to bugs by Bugzilla ID are seen. The hook does not change
-bug status.
-
-The hook updates the Bugzilla database directly. Only Bugzilla
-installations using MySQL are supported.
-
-The hook relies on a Bugzilla script to send bug change notification
-emails. That script changes between Bugzilla versions; the
-'processmail' script used prior to 2.18 is replaced in 2.18 and
-subsequent versions by 'config/sendbugmail.pl'. Note that these will
-be run by Mercurial as the user pushing the change; you will need to
-ensure the Bugzilla install file permissions are set appropriately.
-
-The extension is configured through three different configuration
-sections. These keys are recognized in the [bugzilla] section:
-
-host
- Hostname of the MySQL server holding the Bugzilla database.
-
-db
- Name of the Bugzilla database in MySQL. Default 'bugs'.
-
-user
- Username to use to access MySQL server. Default 'bugs'.
-
-password
- Password to use to access MySQL server.
-
-timeout
- Database connection timeout (seconds). Default 5.
-
-version
- Bugzilla version. Specify '3.0' for Bugzilla versions 3.0 and later,
- '2.18' for Bugzilla versions from 2.18 and '2.16' for versions prior
- to 2.18.
-
-bzuser
- Fallback Bugzilla user name to record comments with, if changeset
- committer cannot be found as a Bugzilla user.
-
-bzdir
- Bugzilla install directory. Used by default notify. Default
- '/var/www/html/bugzilla'.
-
-notify
- The command to run to get Bugzilla to send bug change notification
- emails. Substitutes from a map with 3 keys, 'bzdir', 'id' (bug id)
- and 'user' (committer bugzilla email). Default depends on version;
- from 2.18 it is "cd %(bzdir)s && perl -T contrib/sendbugmail.pl
- %(id)s %(user)s".
-
-regexp
- Regular expression to match bug IDs in changeset commit message.
- Must contain one "()" group. The default expression matches 'Bug
- 1234', 'Bug no. 1234', 'Bug number 1234', 'Bugs 1234,5678', 'Bug
- 1234 and 5678' and variations thereof. Matching is case insensitive.
-
-style
- The style file to use when formatting comments.
-
-template
- Template to use when formatting comments. Overrides style if
- specified. In addition to the usual Mercurial keywords, the
- extension specifies::
-
- {bug} The Bugzilla bug ID.
- {root} The full pathname of the Mercurial repository.
- {webroot} Stripped pathname of the Mercurial repository.
- {hgweb} Base URL for browsing Mercurial repositories.
-
- Default 'changeset {node|short} in repo {root} refers '
- 'to bug {bug}.\\ndetails:\\n\\t{desc|tabindent}'
-
-strip
- The number of slashes to strip from the front of {root} to produce
- {webroot}. Default 0.
-
-usermap
- Path of file containing Mercurial committer ID to Bugzilla user ID
- mappings. If specified, the file should contain one mapping per
- line, "committer"="Bugzilla user". See also the [usermap] section.
-
-The [usermap] section is used to specify mappings of Mercurial
-committer ID to Bugzilla user ID. See also [bugzilla].usermap.
-"committer"="Bugzilla user"
-
-Finally, the [web] section supports one entry:
-
-baseurl
- Base URL for browsing Mercurial repositories. Reference from
- templates as {hgweb}.
-
-Activating the extension::
-
- [extensions]
- bugzilla =
-
- [hooks]
- # run bugzilla hook on every change pulled or pushed in here
- incoming.bugzilla = python:hgext.bugzilla.hook
-
-Example configuration:
-
-This example configuration is for a collection of Mercurial
-repositories in /var/local/hg/repos/ used with a local Bugzilla 3.2
-installation in /opt/bugzilla-3.2. ::
-
- [bugzilla]
- host=localhost
- password=XYZZY
- version=3.0
- bzuser=unknown@domain.com
- bzdir=/opt/bugzilla-3.2
- template=Changeset {node|short} in {root|basename}.
- {hgweb}/{webroot}/rev/{node|short}\\n
- {desc}\\n
- strip=5
-
- [web]
- baseurl=http://dev.domain.com/hg
-
- [usermap]
- user@emaildomain.com=user.name@bugzilladomain.com
-
-Commits add a comment to the Bugzilla bug record of the form::
-
- Changeset 3b16791d6642 in repository-name.
- http://dev.domain.com/hg/repository-name/rev/3b16791d6642
-
- Changeset commit comment. Bug 1234.
-'''
-
-from mercurial.i18n import _
-from mercurial.node import short
-from mercurial import cmdutil, templater, util
-import re, time
-
-MySQLdb = None
-
-def buglist(ids):
- return '(' + ','.join(map(str, ids)) + ')'
-
-class bugzilla_2_16(object):
- '''support for bugzilla version 2.16.'''
-
- def __init__(self, ui):
- self.ui = ui
- host = self.ui.config('bugzilla', 'host', 'localhost')
- user = self.ui.config('bugzilla', 'user', 'bugs')
- passwd = self.ui.config('bugzilla', 'password')
- db = self.ui.config('bugzilla', 'db', 'bugs')
- timeout = int(self.ui.config('bugzilla', 'timeout', 5))
- usermap = self.ui.config('bugzilla', 'usermap')
- if usermap:
- self.ui.readconfig(usermap, sections=['usermap'])
- self.ui.note(_('connecting to %s:%s as %s, password %s\n') %
- (host, db, user, '*' * len(passwd)))
- self.conn = MySQLdb.connect(host=host, user=user, passwd=passwd,
- db=db, connect_timeout=timeout)
- self.cursor = self.conn.cursor()
- self.longdesc_id = self.get_longdesc_id()
- self.user_ids = {}
- self.default_notify = "cd %(bzdir)s && ./processmail %(id)s %(user)s"
-
- def run(self, *args, **kwargs):
- '''run a query.'''
- self.ui.note(_('query: %s %s\n') % (args, kwargs))
- try:
- self.cursor.execute(*args, **kwargs)
- except MySQLdb.MySQLError:
- self.ui.note(_('failed query: %s %s\n') % (args, kwargs))
- raise
-
- def get_longdesc_id(self):
- '''get identity of longdesc field'''
- self.run('select fieldid from fielddefs where name = "longdesc"')
- ids = self.cursor.fetchall()
- if len(ids) != 1:
- raise util.Abort(_('unknown database schema'))
- return ids[0][0]
-
- 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))
- return sorted([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.'''
-
- self.run('''select bug_id from longdescs where
- bug_id in %s and thetext like "%%%s%%"''' %
- (buglist(ids), short(node)))
- unknown = set(ids)
- for (id,) in self.cursor.fetchall():
- self.ui.status(_('bug %d already knows about changeset %s\n') %
- (id, short(node)))
- unknown.discard(id)
- return sorted(unknown)
-
- def notify(self, ids, committer):
- '''tell bugzilla to send mail.'''
-
- self.ui.status(_('telling bugzilla to send mail:\n'))
- (user, userid) = self.get_bugzilla_user(committer)
- for id in ids:
- self.ui.status(_(' bug %s\n') % id)
- cmdfmt = self.ui.config('bugzilla', 'notify', self.default_notify)
- bzdir = self.ui.config('bugzilla', 'bzdir', '/var/www/html/bugzilla')
- try:
- # Backwards-compatible with old notify string, which
- # took one string. This will throw with a new format
- # string.
- cmd = cmdfmt % id
- except TypeError:
- cmd = cmdfmt % {'bzdir': bzdir, 'id': id, 'user': user}
- self.ui.note(_('running notify command %s\n') % cmd)
- fp = util.popen('(%s) 2>&1' % cmd)
- out = fp.read()
- ret = fp.close()
- if ret:
- self.ui.warn(out)
- raise util.Abort(_('bugzilla notify command %s') %
- util.explain_exit(ret)[0])
- self.ui.status(_('done\n'))
-
- def get_user_id(self, user):
- '''look up numeric bugzilla user id.'''
- try:
- return self.user_ids[user]
- except KeyError:
- try:
- userid = int(user)
- except ValueError:
- self.ui.note(_('looking up user %s\n') % user)
- self.run('''select userid from profiles
- where login_name like %s''', user)
- all = self.cursor.fetchall()
- if len(all) != 1:
- raise KeyError(user)
- userid = int(all[0][0])
- self.user_ids[user] = userid
- return userid
-
- def map_committer(self, user):
- '''map name of committer to bugzilla user name.'''
- for committer, bzuser in self.ui.configitems('usermap'):
- if committer.lower() == user.lower():
- return bzuser
- return user
-
- def get_bugzilla_user(self, committer):
- '''see if committer is a registered bugzilla user. Return
- bugzilla username and userid if so. If not, return default
- bugzilla username and userid.'''
- user = self.map_committer(committer)
- try:
- userid = self.get_user_id(user)
- except KeyError:
- try:
- defaultuser = self.ui.config('bugzilla', 'bzuser')
- if not defaultuser:
- raise util.Abort(_('cannot find bugzilla user id for %s') %
- user)
- userid = self.get_user_id(defaultuser)
- user = defaultuser
- except KeyError:
- raise util.Abort(_('cannot find bugzilla user id for %s or %s') %
- (user, defaultuser))
- return (user, userid)
-
- def add_comment(self, bugid, text, committer):
- '''add comment to bug. try adding comment as committer of
- changeset, otherwise as default bugzilla user.'''
- (user, userid) = self.get_bugzilla_user(committer)
- now = time.strftime('%Y-%m-%d %H:%M:%S')
- self.run('''insert into longdescs
- (bug_id, who, bug_when, thetext)
- values (%s, %s, %s, %s)''',
- (bugid, userid, now, text))
- self.run('''insert into bugs_activity (bug_id, who, bug_when, fieldid)
- values (%s, %s, %s, %s)''',
- (bugid, userid, now, self.longdesc_id))
- self.conn.commit()
-
-class bugzilla_2_18(bugzilla_2_16):
- '''support for bugzilla 2.18 series.'''
-
- def __init__(self, ui):
- bugzilla_2_16.__init__(self, ui)
- self.default_notify = \
- "cd %(bzdir)s && perl -T contrib/sendbugmail.pl %(id)s %(user)s"
-
-class bugzilla_3_0(bugzilla_2_18):
- '''support for bugzilla 3.0 series.'''
-
- def __init__(self, ui):
- bugzilla_2_18.__init__(self, ui)
-
- def get_longdesc_id(self):
- '''get identity of longdesc field'''
- self.run('select id from fielddefs where name = "longdesc"')
- ids = self.cursor.fetchall()
- if len(ids) != 1:
- raise util.Abort(_('unknown database schema'))
- return ids[0][0]
-
-class bugzilla(object):
- # supported versions of bugzilla. different versions have
- # different schemas.
- _versions = {
- '2.16': bugzilla_2_16,
- '2.18': bugzilla_2_18,
- '3.0': bugzilla_3_0
- }
-
- _default_bug_re = (r'bugs?\s*,?\s*(?:#|nos?\.?|num(?:ber)?s?)?\s*'
- r'((?:\d+\s*(?:,?\s*(?:and)?)?\s*)+)')
-
- _bz = None
-
- def __init__(self, ui, repo):
- self.ui = ui
- self.repo = repo
-
- def bz(self):
- '''return object that knows how to talk to bugzilla version in
- use.'''
-
- if bugzilla._bz is None:
- bzversion = self.ui.config('bugzilla', 'version')
- try:
- bzclass = bugzilla._versions[bzversion]
- except KeyError:
- raise util.Abort(_('bugzilla version %s not supported') %
- bzversion)
- bugzilla._bz = bzclass(self.ui)
- return bugzilla._bz
-
- def __getattr__(self, key):
- return getattr(self.bz(), key)
-
- _bug_re = None
- _split_re = None
-
- def find_bug_ids(self, ctx):
- '''find valid bug ids that are referred to in changeset
- comments and that do not already have references to this
- changeset.'''
-
- if bugzilla._bug_re is None:
- bugzilla._bug_re = re.compile(
- self.ui.config('bugzilla', 'regexp', bugzilla._default_bug_re),
- re.IGNORECASE)
- bugzilla._split_re = re.compile(r'\D+')
- start = 0
- ids = set()
- while True:
- m = bugzilla._bug_re.search(ctx.description(), start)
- if not m:
- break
- start = m.end()
- for id in bugzilla._split_re.split(m.group(1)):
- if not id:
- continue
- ids.add(int(id))
- if ids:
- ids = self.filter_real_bug_ids(ids)
- if ids:
- ids = self.filter_unknown_bug_ids(ctx.node(), ids)
- return ids
-
- def update(self, bugid, ctx):
- '''update bugzilla bug with reference to changeset.'''
-
- def webroot(root):
- '''strip leading prefix of repo root and turn into
- url-safe path.'''
- count = int(self.ui.config('bugzilla', 'strip', 0))
- root = util.pconvert(root)
- while count > 0:
- c = root.find('/')
- if c == -1:
- break
- root = root[c + 1:]
- count -= 1
- return root
-
- mapfile = self.ui.config('bugzilla', 'style')
- tmpl = self.ui.config('bugzilla', 'template')
- t = cmdutil.changeset_templater(self.ui, self.repo,
- False, None, mapfile, False)
- if not mapfile and not tmpl:
- tmpl = _('changeset {node|short} in repo {root} refers '
- 'to bug {bug}.\ndetails:\n\t{desc|tabindent}')
- if tmpl:
- tmpl = templater.parsestring(tmpl, quoted=False)
- t.use_template(tmpl)
- self.ui.pushbuffer()
- t.show(ctx, changes=ctx.changeset(),
- bug=str(bugid),
- hgweb=self.ui.config('web', 'baseurl'),
- root=self.repo.root,
- webroot=webroot(self.repo.root))
- data = self.ui.popbuffer()
- self.add_comment(bugid, data, util.email(ctx.user()))
-
-def hook(ui, repo, hooktype, node=None, **kwargs):
- '''add comment to bugzilla for each changeset that refers to a
- bugzilla bug id. only add a comment once per bug, so same change
- seen multiple times does not fill bug with duplicate data.'''
- try:
- import MySQLdb as mysql
- global MySQLdb
- MySQLdb = mysql
- except ImportError, err:
- raise util.Abort(_('python mysql support not available: %s') % err)
-
- if node is None:
- raise util.Abort(_('hook type %s does not pass a changeset id') %
- hooktype)
- try:
- bz = bugzilla(ui, repo)
- ctx = repo[node]
- ids = bz.find_bug_ids(ctx)
- if ids:
- for id in ids:
- bz.update(id, ctx)
- bz.notify(ids, util.email(ctx.user()))
- except MySQLdb.MySQLError, err:
- raise util.Abort(_('database error: %s') % err.args[1])
-
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.pyo
deleted file mode 100644
index b4bfa04..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/bugzilla.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.py
deleted file mode 100644
index da2fe9c..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Mercurial extension to provide the 'hg children' command
-#
-# Copyright 2007 by Intevation GmbH <intevation@intevation.de>
-#
-# Author(s):
-# Thomas Arendsen Hein <thomas@intevation.de>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to display child changesets'''
-
-from mercurial import cmdutil
-from mercurial.commands import templateopts
-from mercurial.i18n import _
-
-
-def children(ui, repo, file_=None, **opts):
- """show the children of the given or working directory revision
-
- Print the children of the working directory's revisions. If a
- revision is given via -r/--rev, the children of that revision will
- be printed. If a file argument is given, revision in which the
- file was last changed (after the working directory revision or the
- argument to --rev if given) is printed.
- """
- rev = opts.get('rev')
- if file_:
- ctx = repo.filectx(file_, changeid=rev)
- else:
- ctx = repo[rev]
-
- displayer = cmdutil.show_changeset(ui, repo, opts)
- for cctx in ctx.children():
- displayer.show(cctx)
- displayer.close()
-
-cmdtable = {
- "children":
- (children,
- [('r', 'rev', '',
- _('show children of the specified revision'), _('REV')),
- ] + templateopts,
- _('hg children [-r REV] [FILE]')),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.pyo
deleted file mode 100644
index 05aecd2..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/children.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.py
deleted file mode 100644
index 32e481f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# churn.py - create a graph of revisions count grouped by template
-#
-# Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
-# Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to display statistics about repository history'''
-
-from mercurial.i18n import _
-from mercurial import patch, cmdutil, util, templater, commands
-import os
-import time, datetime
-
-def maketemplater(ui, repo, tmpl):
- tmpl = templater.parsestring(tmpl, quoted=False)
- try:
- t = cmdutil.changeset_templater(ui, repo, False, None, None, False)
- except SyntaxError, inst:
- raise util.Abort(inst.args[0])
- t.use_template(tmpl)
- return t
-
-def changedlines(ui, repo, ctx1, ctx2, fns):
- added, removed = 0, 0
- fmatch = cmdutil.matchfiles(repo, fns)
- diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
- for l in diff.split('\n'):
- if l.startswith("+") and not l.startswith("+++ "):
- added += 1
- elif l.startswith("-") and not l.startswith("--- "):
- removed += 1
- return (added, removed)
-
-def countrate(ui, repo, amap, *pats, **opts):
- """Calculate stats"""
- if opts.get('dateformat'):
- def getkey(ctx):
- t, tz = ctx.date()
- date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
- return date.strftime(opts['dateformat'])
- else:
- tmpl = opts.get('template', '{author|email}')
- tmpl = maketemplater(ui, repo, tmpl)
- def getkey(ctx):
- ui.pushbuffer()
- tmpl.show(ctx)
- return ui.popbuffer()
-
- state = {'count': 0}
- rate = {}
- df = False
- if opts.get('date'):
- df = util.matchdate(opts['date'])
-
- m = cmdutil.match(repo, pats, opts)
- def prep(ctx, fns):
- rev = ctx.rev()
- if df and not df(ctx.date()[0]): # doesn't match date format
- return
-
- key = getkey(ctx)
- key = amap.get(key, key) # alias remap
- key = key.strip() # ignore leading and trailing spaces
- if opts.get('changesets'):
- rate[key] = (rate.get(key, (0,))[0] + 1, 0)
- else:
- parents = ctx.parents()
- if len(parents) > 1:
- ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
- return
-
- ctx1 = parents[0]
- lines = changedlines(ui, repo, ctx1, ctx, fns)
- rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
-
- state['count'] += 1
- ui.progress(_('analyzing'), state['count'], total=len(repo))
-
- for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
- continue
-
- ui.progress(_('analyzing'), None)
-
- return rate
-
-
-def churn(ui, repo, *pats, **opts):
- '''histogram of changes to the repository
-
- This command will display a histogram representing the number
- of changed lines or revisions, grouped according to the given
- template. The default template will group changes by author.
- The --dateformat option may be used to group the results by
- date instead.
-
- Statistics are based on the number of changed lines, or
- alternatively the number of matching revisions if the
- --changesets option is specified.
-
- Examples::
-
- # display count of changed lines for every committer
- hg churn -t '{author|email}'
-
- # display daily activity graph
- hg churn -f '%H' -s -c
-
- # display activity of developers by month
- hg churn -f '%Y-%m' -s -c
-
- # display count of lines changed in every year
- hg churn -f '%Y' -s
-
- It is possible to map alternate email addresses to a main address
- by providing a file using the following format::
-
- <alias email> = <actual email>
-
- Such a file may be specified with the --aliases option, otherwise
- a .hgchurn file will be looked for in the working directory root.
- '''
- def pad(s, l):
- return (s + " " * l)[:l]
-
- amap = {}
- aliases = opts.get('aliases')
- if not aliases and os.path.exists(repo.wjoin('.hgchurn')):
- aliases = repo.wjoin('.hgchurn')
- if aliases:
- for l in open(aliases, "r"):
- try:
- alias, actual = l.split('=' in l and '=' or None, 1)
- amap[alias.strip()] = actual.strip()
- except ValueError:
- l = l.strip()
- if l:
- ui.warn(_("skipping malformed alias: %s\n" % l))
- continue
-
- rate = countrate(ui, repo, amap, *pats, **opts).items()
- if not rate:
- return
-
- sortkey = ((not opts.get('sort')) and (lambda x: -sum(x[1])) or None)
- rate.sort(key=sortkey)
-
- # Be careful not to have a zero maxcount (issue833)
- maxcount = float(max(sum(v) for k, v in rate)) or 1.0
- maxname = max(len(k) for k, v in rate)
-
- ttywidth = ui.termwidth()
- ui.debug("assuming %i character terminal\n" % ttywidth)
- width = ttywidth - maxname - 2 - 2 - 2
-
- if opts.get('diffstat'):
- width -= 15
- def format(name, diffstat):
- added, removed = diffstat
- return "%s %15s %s%s\n" % (pad(name, maxname),
- '+%d/-%d' % (added, removed),
- ui.label('+' * charnum(added),
- 'diffstat.inserted'),
- ui.label('-' * charnum(removed),
- 'diffstat.deleted'))
- else:
- width -= 6
- def format(name, count):
- return "%s %6d %s\n" % (pad(name, maxname), sum(count),
- '*' * charnum(sum(count)))
-
- def charnum(count):
- return int(round(count * width / maxcount))
-
- for name, count in rate:
- ui.write(format(name, count))
-
-
-cmdtable = {
- "churn":
- (churn,
- [('r', 'rev', [],
- _('count rate for the specified revision or range'), _('REV')),
- ('d', 'date', '',
- _('count rate for revisions matching date spec'), _('DATE')),
- ('t', 'template', '{author|email}',
- _('template to group changesets'), _('TEMPLATE')),
- ('f', 'dateformat', '',
- _('strftime-compatible format for grouping by date'), _('FORMAT')),
- ('c', 'changesets', False, _('count rate by number of changesets')),
- ('s', 'sort', False, _('sort by key (default: sort by count)')),
- ('', 'diffstat', False, _('display added/removed lines separately')),
- ('', 'aliases', '',
- _('file with email aliases'), _('FILE')),
- ] + commands.walkopts,
- _("hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]")),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.pyo
deleted file mode 100644
index 90d9a2d..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/churn.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.py
deleted file mode 100644
index df78f8d..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# color.py color output for the status and qseries commands
-#
-# Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-'''colorize output from some commands
-
-This extension modifies the status and resolve commands to add color to their
-output to reflect file status, the qseries command to add color to reflect
-patch status (applied, unapplied, missing), and to diff-related
-commands to highlight additions, removals, diff headers, and trailing
-whitespace.
-
-Other effects in addition to color, like bold and underlined text, are
-also available. Effects are rendered with the ECMA-48 SGR control
-function (aka ANSI escape codes). This module also provides the
-render_text function, which can be used to add effects to any text.
-
-Default effects may be overridden from your configuration file::
-
- [color]
- status.modified = blue bold underline red_background
- status.added = green bold
- status.removed = red bold blue_background
- status.deleted = cyan bold underline
- status.unknown = magenta bold underline
- status.ignored = black bold
-
- # 'none' turns off all effects
- status.clean = none
- status.copied = none
-
- qseries.applied = blue bold underline
- qseries.unapplied = black bold
- qseries.missing = red bold
-
- diff.diffline = bold
- diff.extended = cyan bold
- diff.file_a = red bold
- diff.file_b = green bold
- diff.hunk = magenta
- diff.deleted = red
- diff.inserted = green
- diff.changed = white
- diff.trailingwhitespace = bold red_background
-
- resolve.unresolved = red bold
- resolve.resolved = green bold
-
- bookmarks.current = green
-
- branches.active = none
- branches.closed = black bold
- branches.current = green
- branches.inactive = none
-
-The color extension will try to detect whether to use ANSI codes or
-Win32 console APIs, unless it is made explicit::
-
- [color]
- mode = ansi
-
-Any value other than 'ansi', 'win32', or 'auto' will disable color.
-
-'''
-
-import os
-
-from mercurial import commands, dispatch, extensions, ui as uimod, util
-from mercurial.i18n import _
-
-# start and stop parameters for effects
-_effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
- 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
- 'italic': 3, 'underline': 4, 'inverse': 7,
- 'black_background': 40, 'red_background': 41,
- 'green_background': 42, 'yellow_background': 43,
- 'blue_background': 44, 'purple_background': 45,
- 'cyan_background': 46, 'white_background': 47}
-
-_styles = {'grep.match': 'red bold',
- 'branches.active': 'none',
- 'branches.closed': 'black bold',
- 'branches.current': 'green',
- 'branches.inactive': 'none',
- 'diff.changed': 'white',
- 'diff.deleted': 'red',
- 'diff.diffline': 'bold',
- 'diff.extended': 'cyan bold',
- 'diff.file_a': 'red bold',
- 'diff.file_b': 'green bold',
- 'diff.hunk': 'magenta',
- 'diff.inserted': 'green',
- 'diff.trailingwhitespace': 'bold red_background',
- 'diffstat.deleted': 'red',
- 'diffstat.inserted': 'green',
- 'log.changeset': 'yellow',
- 'resolve.resolved': 'green bold',
- 'resolve.unresolved': 'red bold',
- 'status.added': 'green bold',
- 'status.clean': 'none',
- 'status.copied': 'none',
- 'status.deleted': 'cyan bold underline',
- 'status.ignored': 'black bold',
- 'status.modified': 'blue bold',
- 'status.removed': 'red bold',
- 'status.unknown': 'magenta bold underline'}
-
-
-def render_effects(text, effects):
- 'Wrap text in commands to turn on each effect.'
- if not text:
- return text
- start = [str(_effects[e]) for e in ['none'] + effects.split()]
- start = '\033[' + ';'.join(start) + 'm'
- stop = '\033[' + str(_effects['none']) + 'm'
- return ''.join([start, text, stop])
-
-def extstyles():
- for name, ext in extensions.extensions():
- _styles.update(getattr(ext, 'colortable', {}))
-
-def configstyles(ui):
- for status, cfgeffects in ui.configitems('color'):
- if '.' not in status:
- continue
- cfgeffects = ui.configlist('color', status)
- if cfgeffects:
- good = []
- for e in cfgeffects:
- if e in _effects:
- good.append(e)
- else:
- ui.warn(_("ignoring unknown color/effect %r "
- "(configured in color.%s)\n")
- % (e, status))
- _styles[status] = ' '.join(good)
-
-class colorui(uimod.ui):
- def popbuffer(self, labeled=False):
- if labeled:
- return ''.join(self.label(a, label) for a, label
- in self._buffers.pop())
- return ''.join(a for a, label in self._buffers.pop())
-
- _colormode = 'ansi'
- def write(self, *args, **opts):
- label = opts.get('label', '')
- if self._buffers:
- self._buffers[-1].extend([(str(a), label) for a in args])
- elif self._colormode == 'win32':
- for a in args:
- win32print(a, super(colorui, self).write, **opts)
- else:
- return super(colorui, self).write(
- *[self.label(str(a), label) for a in args], **opts)
-
- def write_err(self, *args, **opts):
- label = opts.get('label', '')
- if self._colormode == 'win32':
- for a in args:
- win32print(a, super(colorui, self).write_err, **opts)
- else:
- return super(colorui, self).write_err(
- *[self.label(str(a), label) for a in args], **opts)
-
- def label(self, msg, label):
- effects = []
- for l in label.split():
- s = _styles.get(l, '')
- if s:
- effects.append(s)
- effects = ''.join(effects)
- if effects:
- return '\n'.join([render_effects(s, effects)
- for s in msg.split('\n')])
- return msg
-
-
-def uisetup(ui):
- if ui.plain():
- return
- mode = ui.config('color', 'mode', 'auto')
- if mode == 'auto':
- if os.name == 'nt' and 'TERM' not in os.environ:
- # looks line a cmd.exe console, use win32 API or nothing
- mode = w32effects and 'win32' or 'none'
- else:
- mode = 'ansi'
- if mode == 'win32':
- if w32effects is None:
- # only warn if color.mode is explicitly set to win32
- ui.warn(_('win32console not found, please install pywin32\n'))
- return
- _effects.update(w32effects)
- elif mode != 'ansi':
- return
- def colorcmd(orig, ui_, opts, cmd, cmdfunc):
- coloropt = opts['color']
- auto = coloropt == 'auto'
- always = util.parsebool(coloropt)
- if (always or
- (always is None and
- (auto and (os.environ.get('TERM') != 'dumb' and ui_.formatted())))):
- colorui._colormode = mode
- colorui.__bases__ = (ui_.__class__,)
- ui_.__class__ = colorui
- extstyles()
- configstyles(ui_)
- return orig(ui_, opts, cmd, cmdfunc)
- extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
-
-def extsetup(ui):
- commands.globalopts.append(
- ('', 'color', 'auto',
- # i18n: 'always', 'auto', and 'never' are keywords and should
- # not be translated
- _("when to colorize (boolean, always, auto, or never)"),
- _('TYPE')))
-
-try:
- import re, pywintypes, win32console as win32c
-
- # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
- w32effects = {
- 'none': -1,
- 'black': 0,
- 'red': win32c.FOREGROUND_RED,
- 'green': win32c.FOREGROUND_GREEN,
- 'yellow': win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN,
- 'blue': win32c.FOREGROUND_BLUE,
- 'magenta': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_RED,
- 'cyan': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_GREEN,
- 'white': (win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN |
- win32c.FOREGROUND_BLUE),
- 'bold': win32c.FOREGROUND_INTENSITY,
- 'black_background': 0x100, # unused value > 0x0f
- 'red_background': win32c.BACKGROUND_RED,
- 'green_background': win32c.BACKGROUND_GREEN,
- 'yellow_background': win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN,
- 'blue_background': win32c.BACKGROUND_BLUE,
- 'purple_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_RED,
- 'cyan_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_GREEN,
- 'white_background': (win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN |
- win32c.BACKGROUND_BLUE),
- 'bold_background': win32c.BACKGROUND_INTENSITY,
- 'underline': win32c.COMMON_LVB_UNDERSCORE, # double-byte charsets only
- 'inverse': win32c.COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
- }
-
- passthrough = set([win32c.FOREGROUND_INTENSITY,
- win32c.BACKGROUND_INTENSITY,
- win32c.COMMON_LVB_UNDERSCORE,
- win32c.COMMON_LVB_REVERSE_VIDEO])
-
- try:
- stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE)
- if stdout is None:
- raise ImportError()
- origattr = stdout.GetConsoleScreenBufferInfo()['Attributes']
- except pywintypes.error:
- # stdout may be defined but not support
- # GetConsoleScreenBufferInfo(), when called from subprocess or
- # redirected.
- raise ImportError()
- ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL)
-
- def win32print(text, orig, **opts):
- label = opts.get('label', '')
- attr = origattr
-
- def mapcolor(val, attr):
- if val == -1:
- return origattr
- elif val in passthrough:
- return attr | val
- elif val > 0x0f:
- return (val & 0x70) | (attr & 0x8f)
- else:
- return (val & 0x07) | (attr & 0xf8)
-
- # determine console attributes based on labels
- for l in label.split():
- style = _styles.get(l, '')
- for effect in style.split():
- attr = mapcolor(w32effects[effect], attr)
-
- # hack to ensure regexp finds data
- if not text.startswith('\033['):
- text = '\033[m' + text
-
- # Look for ANSI-like codes embedded in text
- m = re.match(ansire, text)
- while m:
- for sattr in m.group(1).split(';'):
- if sattr:
- attr = mapcolor(int(sattr), attr)
- stdout.SetConsoleTextAttribute(attr)
- orig(m.group(2), **opts)
- m = re.match(ansire, m.group(3))
-
- # Explicity reset original attributes
- stdout.SetConsoleTextAttribute(origattr)
-
-except ImportError:
- w32effects = None
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.pyo
deleted file mode 100644
index 2f131ee..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.py
deleted file mode 100644
index be7aca5..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# convert.py Foreign SCM converter
-#
-# Copyright 2005-2007 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 revisions from foreign VCS repositories into Mercurial'''
-
-import convcmd
-import cvsps
-import subversion
-from mercurial import commands
-from mercurial.i18n import _
-
-# Commands definition was moved elsewhere to ease demandload job.
-
-def convert(ui, src, dest=None, revmapfile=None, **opts):
- """convert a foreign SCM repository to a Mercurial one.
-
- Accepted source formats [identifiers]:
-
- - Mercurial [hg]
- - CVS [cvs]
- - Darcs [darcs]
- - git [git]
- - Subversion [svn]
- - Monotone [mtn]
- - GNU Arch [gnuarch]
- - Bazaar [bzr]
- - Perforce [p4]
-
- Accepted destination formats [identifiers]:
-
- - Mercurial [hg]
- - Subversion [svn] (history on branches is not preserved)
-
- If no revision is given, all revisions will be converted.
- Otherwise, convert will only import up to the named revision
- (given in a format understood by the source).
-
- If no destination directory name is specified, it defaults to the
- basename of the source with ``-hg`` appended. If the destination
- repository doesn't exist, it will be created.
-
- By default, all sources except Mercurial will use --branchsort.
- Mercurial uses --sourcesort to preserve original revision numbers
- order. Sort modes have the following effects:
-
- --branchsort convert from parent to child revision when possible,
- which means branches are usually converted one after
- the other. It generates more compact repositories.
-
- --datesort sort revisions by date. Converted repositories have
- good-looking changelogs but are often an order of
- magnitude larger than the same ones generated by
- --branchsort.
-
- --sourcesort try to preserve source revisions order, only
- supported by Mercurial sources.
-
- If <REVMAP> isn't given, it will be put in a default location
- (<dest>/.hg/shamap by default). The <REVMAP> is a simple text file
- that maps each source commit ID to the destination ID for that
- revision, like so::
-
- <source ID> <destination ID>
-
- If the file doesn't exist, it's automatically created. It's
- updated on each commit copied, so :hg:`convert` can be interrupted
- and can be run repeatedly to copy new commits.
-
- The authormap is a simple text file that maps each source commit
- author to a destination commit author. It is handy for source SCMs
- that use unix logins to identify authors (eg: CVS). One line per
- author mapping and the line format is::
-
- source author = destination author
-
- Empty lines and lines starting with a ``#`` are ignored.
-
- The filemap is a file that allows filtering and remapping of files
- and directories. Each line can contain one of the following
- directives::
-
- include path/to/file-or-dir
-
- exclude path/to/file-or-dir
-
- rename path/to/source path/to/destination
-
- Comment lines start with ``#``. A specified path matches if it
- equals the full relative name of a file or one of its parent
- directories. The ``include`` or ``exclude`` directive with the
- longest matching path applies, so line order does not matter.
-
- The ``include`` directive causes a file, or all files under a
- directory, to be included in the destination repository, and the
- exclusion of all other files and directories not explicitly
- included. The ``exclude`` directive causes files or directories to
- be omitted. The ``rename`` directive renames a file or directory if
- it is converted. To rename from a subdirectory into the root of
- the repository, use ``.`` as the path to rename to.
-
- The splicemap is a file that allows insertion of synthetic
- history, letting you specify the parents of a revision. This is
- useful if you want to e.g. give a Subversion merge two parents, or
- graft two disconnected series of history together. Each entry
- contains a key, followed by a space, followed by one or two
- comma-separated values::
-
- key parent1, parent2
-
- The key is the revision ID in the source
- revision control system whose parents should be modified (same
- format as a key in .hg/shamap). The values are the revision IDs
- (in either the source or destination revision control system) that
- should be used as the new parents for that node. For example, if
- you have merged "release-1.0" into "trunk", then you should
- specify the revision on "trunk" as the first parent and the one on
- the "release-1.0" branch as the second.
-
- The branchmap is a file that allows you to rename a branch when it is
- being brought in from whatever external repository. When used in
- conjunction with a splicemap, it allows for a powerful combination
- to help fix even the most badly mismanaged repositories and turn them
- into nicely structured Mercurial repositories. The branchmap contains
- lines of the form::
-
- original_branch_name new_branch_name
-
- where "original_branch_name" is the name of the branch in the
- source repository, and "new_branch_name" is the name of the branch
- is the destination repository. No whitespace is allowed in the
- branch names. This can be used to (for instance) move code in one
- repository from "default" to a named branch.
-
- Mercurial Source
- ''''''''''''''''
-
- --config convert.hg.ignoreerrors=False (boolean)
- ignore integrity errors when reading. Use it to fix Mercurial
- repositories with missing revlogs, by converting from and to
- Mercurial.
- --config convert.hg.saverev=False (boolean)
- store original revision ID in changeset (forces target IDs to
- change)
- --config convert.hg.startrev=0 (hg revision identifier)
- convert start revision and its descendants
-
- CVS Source
- ''''''''''
-
- CVS source will use a sandbox (i.e. a checked-out copy) from CVS
- to indicate the starting point of what will be converted. Direct
- access to the repository files is not needed, unless of course the
- repository is :local:. The conversion uses the top level directory
- in the sandbox to find the CVS repository, and then uses CVS rlog
- commands to find files to convert. This means that unless a
- filemap is given, all files under the starting directory will be
- converted, and that any directory reorganization in the CVS
- sandbox is ignored.
-
- The options shown are the defaults.
-
- --config convert.cvsps.cache=True (boolean)
- Set to False to disable remote log caching, for testing and
- debugging purposes.
- --config convert.cvsps.fuzz=60 (integer)
- Specify the maximum time (in seconds) that is allowed between
- commits with identical user and log message in a single
- changeset. When very large files were checked in as part of a
- changeset then the default may not be long enough.
- --config convert.cvsps.mergeto='{{mergetobranch ([-\\w]+)}}'
- Specify a regular expression to which commit log messages are
- matched. If a match occurs, then the conversion process will
- insert a dummy revision merging the branch on which this log
- message occurs to the branch indicated in the regex.
- --config convert.cvsps.mergefrom='{{mergefrombranch ([-\\w]+)}}'
- Specify a regular expression to which commit log messages are
- matched. If a match occurs, then the conversion process will
- add the most recent revision on the branch indicated in the
- regex as the second parent of the changeset.
- --config hook.cvslog
- Specify a Python function to be called at the end of gathering
- the CVS log. The function is passed a list with the log entries,
- and can modify the entries in-place, or add or delete them.
- --config hook.cvschangesets
- Specify a Python function to be called after the changesets
- are calculated from the the CVS log. The function is passed
- a list with the changeset entries, and can modify the changesets
- in-place, or add or delete them.
-
- An additional "debugcvsps" Mercurial command allows the builtin
- changeset merging code to be run without doing a conversion. Its
- parameters and output are similar to that of cvsps 2.1. Please see
- the command help for more details.
-
- Subversion Source
- '''''''''''''''''
-
- Subversion source detects classical trunk/branches/tags layouts.
- By default, the supplied "svn://repo/path/" source URL is
- converted as a single branch. If "svn://repo/path/trunk" exists it
- replaces the default branch. If "svn://repo/path/branches" exists,
- its subdirectories are listed as possible branches. If
- "svn://repo/path/tags" exists, it is looked for tags referencing
- converted branches. Default "trunk", "branches" and "tags" values
- can be overridden with following options. Set them to paths
- relative to the source URL, or leave them blank to disable auto
- detection.
-
- --config convert.svn.branches=branches (directory name)
- specify the directory containing branches
- --config convert.svn.tags=tags (directory name)
- specify the directory containing tags
- --config convert.svn.trunk=trunk (directory name)
- specify the name of the trunk branch
-
- Source history can be retrieved starting at a specific revision,
- instead of being integrally converted. Only single branch
- conversions are supported.
-
- --config convert.svn.startrev=0 (svn revision number)
- specify start Subversion revision.
-
- Perforce Source
- '''''''''''''''
-
- The Perforce (P4) importer can be given a p4 depot path or a
- client specification as source. It will convert all files in the
- source to a flat Mercurial repository, ignoring labels, branches
- and integrations. Note that when a depot path is given you then
- usually should specify a target directory, because otherwise the
- target may be named ...-hg.
-
- It is possible to limit the amount of source history to be
- converted by specifying an initial Perforce revision.
-
- --config convert.p4.startrev=0 (perforce changelist number)
- specify initial Perforce revision.
-
- Mercurial Destination
- '''''''''''''''''''''
-
- --config convert.hg.clonebranches=False (boolean)
- dispatch source branches in separate clones.
- --config convert.hg.tagsbranch=default (branch name)
- tag revisions branch name
- --config convert.hg.usebranchnames=True (boolean)
- preserve branch names
-
- """
- return convcmd.convert(ui, src, dest, revmapfile, **opts)
-
-def debugsvnlog(ui, **opts):
- return subversion.debugsvnlog(ui, **opts)
-
-def debugcvsps(ui, *args, **opts):
- '''create changeset information from CVS
-
- This command is intended as a debugging tool for the CVS to
- Mercurial converter, and can be used as a direct replacement for
- cvsps.
-
- Hg debugcvsps reads the CVS rlog for current directory (or any
- named directory) in the CVS repository, and converts the log to a
- series of changesets based on matching commit log entries and
- dates.'''
- return cvsps.debugcvsps(ui, *args, **opts)
-
-commands.norepo += " convert debugsvnlog debugcvsps"
-
-cmdtable = {
- "convert":
- (convert,
- [('', 'authors', '',
- _('username mapping filename (DEPRECATED, use --authormap instead)'),
- _('FILE')),
- ('s', 'source-type', '',
- _('source repository type'), _('TYPE')),
- ('d', 'dest-type', '',
- _('destination repository type'), _('TYPE')),
- ('r', 'rev', '',
- _('import up to target revision REV'), _('REV')),
- ('A', 'authormap', '',
- _('remap usernames using this file'), _('FILE')),
- ('', 'filemap', '',
- _('remap file names using contents of file'), _('FILE')),
- ('', 'splicemap', '',
- _('splice synthesized history into place'), _('FILE')),
- ('', 'branchmap', '',
- _('change branch names while converting'), _('FILE')),
- ('', 'branchsort', None, _('try to sort changesets by branches')),
- ('', 'datesort', None, _('try to sort changesets by date')),
- ('', 'sourcesort', None, _('preserve source changesets order'))],
- _('hg convert [OPTION]... SOURCE [DEST [REVMAP]]')),
- "debugsvnlog":
- (debugsvnlog,
- [],
- 'hg debugsvnlog'),
- "debugcvsps":
- (debugcvsps,
- [
- # Main options shared with cvsps-2.1
- ('b', 'branches', [], _('only return changes on specified branches')),
- ('p', 'prefix', '', _('prefix to remove from file names')),
- ('r', 'revisions', [],
- _('only return changes after or between specified tags')),
- ('u', 'update-cache', None, _("update cvs log cache")),
- ('x', 'new-cache', None, _("create new cvs log cache")),
- ('z', 'fuzz', 60, _('set commit time fuzz in seconds')),
- ('', 'root', '', _('specify cvsroot')),
- # Options specific to builtin cvsps
- ('', 'parents', '', _('show parent changesets')),
- ('', 'ancestors', '', _('show current changeset in ancestor branches')),
- # Options that are ignored for compatibility with cvsps-2.1
- ('A', 'cvs-direct', None, _('ignored for compatibility')),
- ],
- _('hg debugcvsps [OPTION]... [PATH]...')),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.pyo
deleted file mode 100644
index 892b438..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/__init__.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.py
deleted file mode 100644
index cc16258..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# bzr.py - bzr support for the convert extension
-#
-# Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-# This module is for handling 'bzr', that was formerly known as Bazaar-NG;
-# it cannot access 'bar' repositories, but they were never used very much
-
-import os
-from mercurial import demandimport
-# these do not work with demandimport, blacklist
-demandimport.ignore.extend([
- 'bzrlib.transactions',
- 'bzrlib.urlutils',
- 'ElementPath',
- ])
-
-from mercurial.i18n import _
-from mercurial import util
-from common import NoRepo, commit, converter_source
-
-try:
- # bazaar imports
- from bzrlib import branch, revision, errors
- from bzrlib.revisionspec import RevisionSpec
-except ImportError:
- pass
-
-supportedkinds = ('file', 'symlink')
-
-class bzr_source(converter_source):
- """Reads Bazaar repositories by using the Bazaar Python libraries"""
-
- def __init__(self, ui, path, rev=None):
- super(bzr_source, self).__init__(ui, path, rev=rev)
-
- if not os.path.exists(os.path.join(path, '.bzr')):
- raise NoRepo(_('%s does not look like a Bazaar repository')
- % path)
-
- try:
- # access bzrlib stuff
- branch
- except NameError:
- raise NoRepo(_('Bazaar modules could not be loaded'))
-
- path = os.path.abspath(path)
- self._checkrepotype(path)
- self.branch = branch.Branch.open(path)
- self.sourcerepo = self.branch.repository
- self._parentids = {}
-
- def _checkrepotype(self, path):
- # Lightweight checkouts detection is informational but probably
- # fragile at API level. It should not terminate the conversion.
- try:
- from bzrlib import bzrdir
- dir = bzrdir.BzrDir.open_containing(path)[0]
- try:
- tree = dir.open_workingtree(recommend_upgrade=False)
- branch = tree.branch
- except (errors.NoWorkingTree, errors.NotLocalUrl):
- tree = None
- branch = dir.open_branch()
- if (tree is not None and tree.bzrdir.root_transport.base !=
- branch.bzrdir.root_transport.base):
- self.ui.warn(_('warning: lightweight checkouts may cause '
- 'conversion failures, try with a regular '
- 'branch instead.\n'))
- except:
- self.ui.note(_('bzr source type could not be determined\n'))
-
- def before(self):
- """Before the conversion begins, acquire a read lock
- for all the operations that might need it. Fortunately
- read locks don't block other reads or writes to the
- repository, so this shouldn't have any impact on the usage of
- the source repository.
-
- The alternative would be locking on every operation that
- needs locks (there are currently two: getting the file and
- getting the parent map) and releasing immediately after,
- but this approach can take even 40% longer."""
- self.sourcerepo.lock_read()
-
- def after(self):
- self.sourcerepo.unlock()
-
- def getheads(self):
- if not self.rev:
- return [self.branch.last_revision()]
- try:
- r = RevisionSpec.from_string(self.rev)
- info = r.in_history(self.branch)
- except errors.BzrError:
- raise util.Abort(_('%s is not a valid revision in current branch')
- % self.rev)
- return [info.rev_id]
-
- def getfile(self, name, rev):
- revtree = self.sourcerepo.revision_tree(rev)
- fileid = revtree.path2id(name.decode(self.encoding or 'utf-8'))
- kind = None
- if fileid is not None:
- kind = revtree.kind(fileid)
- if kind not in supportedkinds:
- # the file is not available anymore - was deleted
- raise IOError(_('%s is not available in %s anymore') %
- (name, rev))
- mode = self._modecache[(name, rev)]
- if kind == 'symlink':
- target = revtree.get_symlink_target(fileid)
- if target is None:
- raise util.Abort(_('%s.%s symlink has no target')
- % (name, rev))
- return target, mode
- else:
- sio = revtree.get_file(fileid)
- return sio.read(), mode
-
- def getchanges(self, version):
- # set up caches: modecache and revtree
- self._modecache = {}
- self._revtree = self.sourcerepo.revision_tree(version)
- # get the parentids from the cache
- parentids = self._parentids.pop(version)
- # only diff against first parent id
- prevtree = self.sourcerepo.revision_tree(parentids[0])
- return self._gettreechanges(self._revtree, prevtree)
-
- def getcommit(self, version):
- rev = self.sourcerepo.get_revision(version)
- # populate parent id cache
- if not rev.parent_ids:
- parents = []
- self._parentids[version] = (revision.NULL_REVISION,)
- else:
- parents = self._filterghosts(rev.parent_ids)
- self._parentids[version] = parents
-
- return commit(parents=parents,
- date='%d %d' % (rev.timestamp, -rev.timezone),
- author=self.recode(rev.committer),
- # bzr returns bytestrings or unicode, depending on the content
- desc=self.recode(rev.message),
- rev=version)
-
- def gettags(self):
- if not self.branch.supports_tags():
- return {}
- tagdict = self.branch.tags.get_tag_dict()
- bytetags = {}
- for name, rev in tagdict.iteritems():
- bytetags[self.recode(name)] = rev
- return bytetags
-
- def getchangedfiles(self, rev, i):
- self._modecache = {}
- curtree = self.sourcerepo.revision_tree(rev)
- if i is not None:
- parentid = self._parentids[rev][i]
- else:
- # no parent id, get the empty revision
- parentid = revision.NULL_REVISION
-
- prevtree = self.sourcerepo.revision_tree(parentid)
- changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
- return changes
-
- def _gettreechanges(self, current, origin):
- revid = current._revision_id
- changes = []
- renames = {}
- for (fileid, paths, changed_content, versioned, parent, name,
- kind, executable) in current.iter_changes(origin):
-
- if paths[0] == u'' or paths[1] == u'':
- # ignore changes to tree root
- continue
-
- # bazaar tracks directories, mercurial does not, so
- # we have to rename the directory contents
- if kind[1] == 'directory':
- if kind[0] not in (None, 'directory'):
- # Replacing 'something' with a directory, record it
- # so it can be removed.
- changes.append((self.recode(paths[0]), revid))
-
- if None not in paths and paths[0] != paths[1]:
- # neither an add nor an delete - a move
- # rename all directory contents manually
- subdir = origin.inventory.path2id(paths[0])
- # get all child-entries of the directory
- for name, entry in origin.inventory.iter_entries(subdir):
- # hg does not track directory renames
- if entry.kind == 'directory':
- continue
- frompath = self.recode(paths[0] + '/' + name)
- topath = self.recode(paths[1] + '/' + name)
- # register the files as changed
- changes.append((frompath, revid))
- changes.append((topath, revid))
- # add to mode cache
- mode = ((entry.executable and 'x')
- or (entry.kind == 'symlink' and 's')
- or '')
- self._modecache[(topath, revid)] = mode
- # register the change as move
- renames[topath] = frompath
-
- # no futher changes, go to the next change
- continue
-
- # we got unicode paths, need to convert them
- path, topath = [self.recode(part) for part in paths]
-
- if topath is None:
- # file deleted
- changes.append((path, revid))
- continue
-
- # renamed
- if path and path != topath:
- renames[topath] = path
- changes.append((path, revid))
-
- # populate the mode cache
- kind, executable = [e[1] for e in (kind, executable)]
- mode = ((executable and 'x') or (kind == 'symlink' and 'l')
- or '')
- self._modecache[(topath, revid)] = mode
- changes.append((topath, revid))
-
- return changes, renames
-
- def _filterghosts(self, ids):
- """Filters out ghost revisions which hg does not support, see
- <http://bazaar-vcs.org/GhostRevision>
- """
- parentmap = self.sourcerepo.get_parent_map(ids)
- parents = tuple([parent for parent in ids if parent in parentmap])
- return parents
-
- def recode(self, s, encoding=None):
- """This version of recode tries to encode unicode to bytecode,
- and preferably using the UTF-8 codec.
- Other types than Unicode are silently returned, this is by
- intention, e.g. the None-type is not going to be encoded but instead
- just passed through
- """
- if not encoding:
- encoding = self.encoding or 'utf-8'
-
- if isinstance(s, unicode):
- return s.encode(encoding)
- else:
- # leave it alone
- return s
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.pyo
deleted file mode 100644
index ab47e99..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/bzr.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.py
deleted file mode 100644
index fb3865f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.py
+++ /dev/null
@@ -1,389 +0,0 @@
-# common.py - common code for the convert extension
-#
-# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import base64, errno
-import os
-import cPickle as pickle
-from mercurial import util
-from mercurial.i18n import _
-
-def encodeargs(args):
- def encodearg(s):
- lines = base64.encodestring(s)
- lines = [l.splitlines()[0] for l in lines]
- return ''.join(lines)
-
- s = pickle.dumps(args)
- return encodearg(s)
-
-def decodeargs(s):
- s = base64.decodestring(s)
- return pickle.loads(s)
-
-class MissingTool(Exception):
- pass
-
-def checktool(exe, name=None, abort=True):
- name = name or exe
- if not util.find_exe(exe):
- exc = abort and util.Abort or MissingTool
- raise exc(_('cannot find required "%s" tool') % name)
-
-class NoRepo(Exception):
- pass
-
-SKIPREV = 'SKIP'
-
-class commit(object):
- def __init__(self, author, date, desc, parents, branch=None, rev=None,
- extra={}, sortkey=None):
- self.author = author or 'unknown'
- self.date = date or '0 0'
- self.desc = desc
- self.parents = parents
- self.branch = branch
- self.rev = rev
- self.extra = extra
- self.sortkey = sortkey
-
-class converter_source(object):
- """Conversion source interface"""
-
- def __init__(self, ui, path=None, rev=None):
- """Initialize conversion source (or raise NoRepo("message")
- exception if path is not a valid repository)"""
- self.ui = ui
- self.path = path
- self.rev = rev
-
- self.encoding = 'utf-8'
-
- def before(self):
- pass
-
- def after(self):
- pass
-
- def setrevmap(self, revmap):
- """set the map of already-converted revisions"""
- pass
-
- def getheads(self):
- """Return a list of this repository's heads"""
- raise NotImplementedError()
-
- def getfile(self, name, rev):
- """Return a pair (data, mode) where data is the file content
- as a string and mode one of '', 'x' or 'l'. rev is the
- identifier returned by a previous call to getchanges(). Raise
- IOError to indicate that name was deleted in rev.
- """
- raise NotImplementedError()
-
- def getchanges(self, version):
- """Returns a tuple of (files, copies).
-
- files is a sorted list of (filename, id) tuples for all files
- changed between version and its first parent returned by
- getcommit(). id is the source revision id of the file.
-
- copies is a dictionary of dest: source
- """
- raise NotImplementedError()
-
- def getcommit(self, version):
- """Return the commit object for version"""
- raise NotImplementedError()
-
- def gettags(self):
- """Return the tags as a dictionary of name: revision
-
- Tag names must be UTF-8 strings.
- """
- raise NotImplementedError()
-
- def recode(self, s, encoding=None):
- if not encoding:
- encoding = self.encoding or 'utf-8'
-
- if isinstance(s, unicode):
- return s.encode("utf-8")
- try:
- return s.decode(encoding).encode("utf-8")
- except:
- try:
- return s.decode("latin-1").encode("utf-8")
- except:
- return s.decode(encoding, "replace").encode("utf-8")
-
- def getchangedfiles(self, rev, i):
- """Return the files changed by rev compared to parent[i].
-
- i is an index selecting one of the parents of rev. The return
- value should be the list of files that are different in rev and
- this parent.
-
- If rev has no parents, i is None.
-
- This function is only needed to support --filemap
- """
- raise NotImplementedError()
-
- def converted(self, rev, sinkrev):
- '''Notify the source that a revision has been converted.'''
- pass
-
- def hasnativeorder(self):
- """Return true if this source has a meaningful, native revision
- order. For instance, Mercurial revisions are store sequentially
- while there is no such global ordering with Darcs.
- """
- return False
-
- def lookuprev(self, rev):
- """If rev is a meaningful revision reference in source, return
- the referenced identifier in the same format used by getcommit().
- return None otherwise.
- """
- return None
-
-class converter_sink(object):
- """Conversion sink (target) interface"""
-
- def __init__(self, ui, path):
- """Initialize conversion sink (or raise NoRepo("message")
- exception if path is not a valid repository)
-
- created is a list of paths to remove if a fatal error occurs
- later"""
- self.ui = ui
- self.path = path
- self.created = []
-
- def getheads(self):
- """Return a list of this repository's heads"""
- raise NotImplementedError()
-
- def revmapfile(self):
- """Path to a file that will contain lines
- source_rev_id sink_rev_id
- mapping equivalent revision identifiers for each system."""
- raise NotImplementedError()
-
- def authorfile(self):
- """Path to a file that will contain lines
- srcauthor=dstauthor
- mapping equivalent authors identifiers for each system."""
- return None
-
- def putcommit(self, files, copies, parents, commit, source, revmap):
- """Create a revision with all changed files listed in 'files'
- and having listed parents. 'commit' is a commit object
- containing at a minimum the author, date, and message for this
- changeset. 'files' is a list of (path, version) tuples,
- 'copies' is a dictionary mapping destinations to sources,
- 'source' is the source repository, and 'revmap' is a mapfile
- of source revisions to converted revisions. Only getfile() and
- lookuprev() should be called on 'source'.
-
- Note that the sink repository is not told to update itself to
- a particular revision (or even what that revision would be)
- before it receives the file data.
- """
- raise NotImplementedError()
-
- def puttags(self, tags):
- """Put tags into sink.
-
- tags: {tagname: sink_rev_id, ...} where tagname is an UTF-8 string.
- Return a pair (tag_revision, tag_parent_revision), or (None, None)
- if nothing was changed.
- """
- raise NotImplementedError()
-
- def setbranch(self, branch, pbranches):
- """Set the current branch name. Called before the first putcommit
- on the branch.
- branch: branch name for subsequent commits
- pbranches: (converted parent revision, parent branch) tuples"""
- pass
-
- def setfilemapmode(self, active):
- """Tell the destination that we're using a filemap
-
- Some converter_sources (svn in particular) can claim that a file
- was changed in a revision, even if there was no change. This method
- tells the destination that we're using a filemap and that it should
- filter empty revisions.
- """
- pass
-
- def before(self):
- pass
-
- def after(self):
- pass
-
-
-class commandline(object):
- def __init__(self, ui, command):
- self.ui = ui
- self.command = command
-
- def prerun(self):
- pass
-
- def postrun(self):
- pass
-
- def _cmdline(self, cmd, *args, **kwargs):
- cmdline = [self.command, cmd] + list(args)
- for k, v in kwargs.iteritems():
- if len(k) == 1:
- cmdline.append('-' + k)
- else:
- cmdline.append('--' + k.replace('_', '-'))
- try:
- if len(k) == 1:
- cmdline.append('' + v)
- else:
- cmdline[-1] += '=' + v
- except TypeError:
- pass
- cmdline = [util.shellquote(arg) for arg in cmdline]
- if not self.ui.debugflag:
- cmdline += ['2>', util.nulldev]
- cmdline += ['<', util.nulldev]
- cmdline = ' '.join(cmdline)
- return cmdline
-
- def _run(self, cmd, *args, **kwargs):
- cmdline = self._cmdline(cmd, *args, **kwargs)
- self.ui.debug('running: %s\n' % (cmdline,))
- self.prerun()
- try:
- return util.popen(cmdline)
- finally:
- self.postrun()
-
- def run(self, cmd, *args, **kwargs):
- fp = self._run(cmd, *args, **kwargs)
- output = fp.read()
- self.ui.debug(output)
- return output, fp.close()
-
- def runlines(self, cmd, *args, **kwargs):
- fp = self._run(cmd, *args, **kwargs)
- output = fp.readlines()
- self.ui.debug(''.join(output))
- return output, fp.close()
-
- def checkexit(self, status, output=''):
- if status:
- if output:
- self.ui.warn(_('%s error:\n') % self.command)
- self.ui.warn(output)
- msg = util.explain_exit(status)[0]
- raise util.Abort('%s %s' % (self.command, msg))
-
- def run0(self, cmd, *args, **kwargs):
- output, status = self.run(cmd, *args, **kwargs)
- self.checkexit(status, output)
- return output
-
- def runlines0(self, cmd, *args, **kwargs):
- output, status = self.runlines(cmd, *args, **kwargs)
- self.checkexit(status, ''.join(output))
- return output
-
- def getargmax(self):
- if '_argmax' in self.__dict__:
- return self._argmax
-
- # POSIX requires at least 4096 bytes for ARG_MAX
- self._argmax = 4096
- try:
- self._argmax = os.sysconf("SC_ARG_MAX")
- except:
- pass
-
- # Windows shells impose their own limits on command line length,
- # down to 2047 bytes for cmd.exe under Windows NT/2k and 2500 bytes
- # for older 4nt.exe. See http://support.microsoft.com/kb/830473 for
- # details about cmd.exe limitations.
-
- # Since ARG_MAX is for command line _and_ environment, lower our limit
- # (and make happy Windows shells while doing this).
-
- self._argmax = self._argmax / 2 - 1
- return self._argmax
-
- def limit_arglist(self, arglist, cmd, *args, **kwargs):
- limit = self.getargmax() - len(self._cmdline(cmd, *args, **kwargs))
- bytes = 0
- fl = []
- for fn in arglist:
- b = len(fn) + 3
- if bytes + b < limit or len(fl) == 0:
- fl.append(fn)
- bytes += b
- else:
- yield fl
- fl = [fn]
- bytes = b
- if fl:
- yield fl
-
- def xargs(self, arglist, cmd, *args, **kwargs):
- for l in self.limit_arglist(arglist, cmd, *args, **kwargs):
- self.run0(cmd, *(list(args) + l), **kwargs)
-
-class mapfile(dict):
- def __init__(self, ui, path):
- super(mapfile, self).__init__()
- self.ui = ui
- self.path = path
- self.fp = None
- self.order = []
- self._read()
-
- def _read(self):
- if not self.path:
- return
- try:
- fp = open(self.path, 'r')
- except IOError, err:
- if err.errno != errno.ENOENT:
- raise
- return
- for i, line in enumerate(fp):
- try:
- key, value = line.splitlines()[0].rsplit(' ', 1)
- except ValueError:
- raise util.Abort(
- _('syntax error in %s(%d): key/value pair expected')
- % (self.path, i + 1))
- if key not in self:
- self.order.append(key)
- super(mapfile, self).__setitem__(key, value)
- fp.close()
-
- def __setitem__(self, key, value):
- if self.fp is None:
- try:
- self.fp = open(self.path, 'a')
- except IOError, err:
- raise util.Abort(_('could not open map file %r: %s') %
- (self.path, err.strerror))
- self.fp.write('%s %s\n' % (key, value))
- self.fp.flush()
- super(mapfile, self).__setitem__(key, value)
-
- def close(self):
- if self.fp:
- self.fp.close()
- self.fp = None
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.pyo
deleted file mode 100644
index de20000..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/common.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.py
deleted file mode 100644
index ac91b41..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# convcmd - convert extension commands definition
-#
-# Copyright 2005-2007 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.
-
-from common import NoRepo, MissingTool, SKIPREV, mapfile
-from cvs import convert_cvs
-from darcs import darcs_source
-from git import convert_git
-from hg import mercurial_source, mercurial_sink
-from subversion import svn_source, svn_sink
-from monotone import monotone_source
-from gnuarch import gnuarch_source
-from bzr import bzr_source
-from p4 import p4_source
-import filemap
-
-import os, shutil
-from mercurial import hg, util, encoding
-from mercurial.i18n import _
-
-orig_encoding = 'ascii'
-
-def recode(s):
- if isinstance(s, unicode):
- return s.encode(orig_encoding, 'replace')
- else:
- return s.decode('utf-8').encode(orig_encoding, 'replace')
-
-source_converters = [
- ('cvs', convert_cvs, 'branchsort'),
- ('git', convert_git, 'branchsort'),
- ('svn', svn_source, 'branchsort'),
- ('hg', mercurial_source, 'sourcesort'),
- ('darcs', darcs_source, 'branchsort'),
- ('mtn', monotone_source, 'branchsort'),
- ('gnuarch', gnuarch_source, 'branchsort'),
- ('bzr', bzr_source, 'branchsort'),
- ('p4', p4_source, 'branchsort'),
- ]
-
-sink_converters = [
- ('hg', mercurial_sink),
- ('svn', svn_sink),
- ]
-
-def convertsource(ui, path, type, rev):
- exceptions = []
- if type and type not in [s[0] for s in source_converters]:
- raise util.Abort(_('%s: invalid source repository type') % type)
- for name, source, sortmode in source_converters:
- try:
- if not type or name == type:
- return source(ui, path, rev), sortmode
- except (NoRepo, MissingTool), inst:
- exceptions.append(inst)
- if not ui.quiet:
- for inst in exceptions:
- ui.write("%s\n" % inst)
- raise util.Abort(_('%s: missing or unsupported repository') % path)
-
-def convertsink(ui, path, type):
- if type and type not in [s[0] for s in sink_converters]:
- raise util.Abort(_('%s: invalid destination repository type') % type)
- for name, sink in sink_converters:
- try:
- if not type or name == type:
- return sink(ui, path)
- except NoRepo, inst:
- ui.note(_("convert: %s\n") % inst)
- raise util.Abort(_('%s: unknown repository type') % path)
-
-class progresssource(object):
- def __init__(self, ui, source, filecount):
- self.ui = ui
- self.source = source
- self.filecount = filecount
- self.retrieved = 0
-
- def getfile(self, file, rev):
- self.retrieved += 1
- self.ui.progress(_('getting files'), self.retrieved,
- item=file, total=self.filecount)
- return self.source.getfile(file, rev)
-
- def lookuprev(self, rev):
- return self.source.lookuprev(rev)
-
- def close(self):
- self.ui.progress(_('getting files'), None)
-
-class converter(object):
- def __init__(self, ui, source, dest, revmapfile, opts):
-
- self.source = source
- self.dest = dest
- self.ui = ui
- self.opts = opts
- self.commitcache = {}
- self.authors = {}
- self.authorfile = None
-
- # Record converted revisions persistently: maps source revision
- # ID to target revision ID (both strings). (This is how
- # incremental conversions work.)
- self.map = mapfile(ui, revmapfile)
-
- # Read first the dst author map if any
- authorfile = self.dest.authorfile()
- if authorfile and os.path.exists(authorfile):
- self.readauthormap(authorfile)
- # Extend/Override with new author map if necessary
- if opts.get('authormap'):
- self.readauthormap(opts.get('authormap'))
- self.authorfile = self.dest.authorfile()
-
- self.splicemap = mapfile(ui, opts.get('splicemap'))
- self.branchmap = mapfile(ui, opts.get('branchmap'))
-
- def walktree(self, heads):
- '''Return a mapping that identifies the uncommitted parents of every
- uncommitted changeset.'''
- visit = heads
- known = set()
- parents = {}
- while visit:
- n = visit.pop(0)
- if n in known or n in self.map:
- continue
- known.add(n)
- self.ui.progress(_('scanning'), len(known), unit=_('revisions'))
- commit = self.cachecommit(n)
- parents[n] = []
- for p in commit.parents:
- parents[n].append(p)
- visit.append(p)
- self.ui.progress(_('scanning'), None)
-
- return parents
-
- def toposort(self, parents, sortmode):
- '''Return an ordering such that every uncommitted changeset is
- preceeded by all its uncommitted ancestors.'''
-
- def mapchildren(parents):
- """Return a (children, roots) tuple where 'children' maps parent
- revision identifiers to children ones, and 'roots' is the list of
- revisions without parents. 'parents' must be a mapping of revision
- identifier to its parents ones.
- """
- visit = parents.keys()
- seen = set()
- children = {}
- roots = []
-
- while visit:
- n = visit.pop(0)
- if n in seen:
- continue
- seen.add(n)
- # Ensure that nodes without parents are present in the
- # 'children' mapping.
- children.setdefault(n, [])
- hasparent = False
- for p in parents[n]:
- if not p in self.map:
- visit.append(p)
- hasparent = True
- children.setdefault(p, []).append(n)
- if not hasparent:
- roots.append(n)
-
- return children, roots
-
- # Sort functions are supposed to take a list of revisions which
- # can be converted immediately and pick one
-
- def makebranchsorter():
- """If the previously converted revision has a child in the
- eligible revisions list, pick it. Return the list head
- otherwise. Branch sort attempts to minimize branch
- switching, which is harmful for Mercurial backend
- compression.
- """
- prev = [None]
- def picknext(nodes):
- next = nodes[0]
- for n in nodes:
- if prev[0] in parents[n]:
- next = n
- break
- prev[0] = next
- return next
- return picknext
-
- def makesourcesorter():
- """Source specific sort."""
- keyfn = lambda n: self.commitcache[n].sortkey
- def picknext(nodes):
- return sorted(nodes, key=keyfn)[0]
- return picknext
-
- def makedatesorter():
- """Sort revisions by date."""
- dates = {}
- def getdate(n):
- if n not in dates:
- dates[n] = util.parsedate(self.commitcache[n].date)
- return dates[n]
-
- def picknext(nodes):
- return min([(getdate(n), n) for n in nodes])[1]
-
- return picknext
-
- if sortmode == 'branchsort':
- picknext = makebranchsorter()
- elif sortmode == 'datesort':
- picknext = makedatesorter()
- elif sortmode == 'sourcesort':
- picknext = makesourcesorter()
- else:
- raise util.Abort(_('unknown sort mode: %s') % sortmode)
-
- children, actives = mapchildren(parents)
-
- s = []
- pendings = {}
- while actives:
- n = picknext(actives)
- actives.remove(n)
- s.append(n)
-
- # Update dependents list
- for c in children.get(n, []):
- if c not in pendings:
- pendings[c] = [p for p in parents[c] if p not in self.map]
- try:
- pendings[c].remove(n)
- except ValueError:
- raise util.Abort(_('cycle detected between %s and %s')
- % (recode(c), recode(n)))
- if not pendings[c]:
- # Parents are converted, node is eligible
- actives.insert(0, c)
- pendings[c] = None
-
- if len(s) != len(parents):
- raise util.Abort(_("not all revisions were sorted"))
-
- return s
-
- def writeauthormap(self):
- authorfile = self.authorfile
- if authorfile:
- self.ui.status(_('Writing author map file %s\n') % authorfile)
- ofile = open(authorfile, 'w+')
- for author in self.authors:
- ofile.write("%s=%s\n" % (author, self.authors[author]))
- ofile.close()
-
- def readauthormap(self, authorfile):
- afile = open(authorfile, 'r')
- for line in afile:
-
- line = line.strip()
- if not line or line.startswith('#'):
- continue
-
- try:
- srcauthor, dstauthor = line.split('=', 1)
- except ValueError:
- msg = _('Ignoring bad line in author map file %s: %s\n')
- self.ui.warn(msg % (authorfile, line.rstrip()))
- continue
-
- srcauthor = srcauthor.strip()
- dstauthor = dstauthor.strip()
- if self.authors.get(srcauthor) in (None, dstauthor):
- msg = _('mapping author %s to %s\n')
- self.ui.debug(msg % (srcauthor, dstauthor))
- self.authors[srcauthor] = dstauthor
- continue
-
- m = _('overriding mapping for author %s, was %s, will be %s\n')
- self.ui.status(m % (srcauthor, self.authors[srcauthor], dstauthor))
-
- afile.close()
-
- def cachecommit(self, rev):
- commit = self.source.getcommit(rev)
- commit.author = self.authors.get(commit.author, commit.author)
- commit.branch = self.branchmap.get(commit.branch, commit.branch)
- self.commitcache[rev] = commit
- return commit
-
- def copy(self, rev):
- commit = self.commitcache[rev]
-
- changes = self.source.getchanges(rev)
- if isinstance(changes, basestring):
- if changes == SKIPREV:
- dest = SKIPREV
- else:
- dest = self.map[changes]
- self.map[rev] = dest
- return
- files, copies = changes
- pbranches = []
- if commit.parents:
- for prev in commit.parents:
- if prev not in self.commitcache:
- self.cachecommit(prev)
- pbranches.append((self.map[prev],
- self.commitcache[prev].branch))
- self.dest.setbranch(commit.branch, pbranches)
- try:
- parents = self.splicemap[rev].replace(',', ' ').split()
- self.ui.status(_('spliced in %s as parents of %s\n') %
- (parents, rev))
- parents = [self.map.get(p, p) for p in parents]
- except KeyError:
- parents = [b[0] for b in pbranches]
- source = progresssource(self.ui, self.source, len(files))
- newnode = self.dest.putcommit(files, copies, parents, commit,
- source, self.map)
- source.close()
- self.source.converted(rev, newnode)
- self.map[rev] = newnode
-
- def convert(self, sortmode):
- try:
- self.source.before()
- self.dest.before()
- self.source.setrevmap(self.map)
- self.ui.status(_("scanning source...\n"))
- heads = self.source.getheads()
- parents = self.walktree(heads)
- self.ui.status(_("sorting...\n"))
- t = self.toposort(parents, sortmode)
- num = len(t)
- c = None
-
- self.ui.status(_("converting...\n"))
- for i, c in enumerate(t):
- num -= 1
- desc = self.commitcache[c].desc
- if "\n" in desc:
- desc = desc.splitlines()[0]
- # convert log message to local encoding without using
- # tolocal() because the encoding.encoding convert()
- # uses is 'utf-8'
- self.ui.status("%d %s\n" % (num, recode(desc)))
- self.ui.note(_("source: %s\n") % recode(c))
- self.ui.progress(_('converting'), i, unit=_('revisions'),
- total=len(t))
- self.copy(c)
- self.ui.progress(_('converting'), None)
-
- tags = self.source.gettags()
- ctags = {}
- for k in tags:
- v = tags[k]
- if self.map.get(v, SKIPREV) != SKIPREV:
- ctags[k] = self.map[v]
-
- if c and ctags:
- nrev, tagsparent = self.dest.puttags(ctags)
- if nrev and tagsparent:
- # write another hash correspondence to override the previous
- # one so we don't end up with extra tag heads
- tagsparents = [e for e in self.map.iteritems()
- if e[1] == tagsparent]
- if tagsparents:
- self.map[tagsparents[0][0]] = nrev
-
- self.writeauthormap()
- finally:
- self.cleanup()
-
- def cleanup(self):
- try:
- self.dest.after()
- finally:
- self.source.after()
- self.map.close()
-
-def convert(ui, src, dest=None, revmapfile=None, **opts):
- global orig_encoding
- orig_encoding = encoding.encoding
- encoding.encoding = 'UTF-8'
-
- # support --authors as an alias for --authormap
- if not opts.get('authormap'):
- opts['authormap'] = opts.get('authors')
-
- if not dest:
- dest = hg.defaultdest(src) + "-hg"
- ui.status(_("assuming destination %s\n") % dest)
-
- destc = convertsink(ui, dest, opts.get('dest_type'))
-
- try:
- srcc, defaultsort = convertsource(ui, src, opts.get('source_type'),
- opts.get('rev'))
- except Exception:
- for path in destc.created:
- shutil.rmtree(path, True)
- raise
-
- sortmodes = ('branchsort', 'datesort', 'sourcesort')
- sortmode = [m for m in sortmodes if opts.get(m)]
- if len(sortmode) > 1:
- raise util.Abort(_('more than one sort mode specified'))
- sortmode = sortmode and sortmode[0] or defaultsort
- if sortmode == 'sourcesort' and not srcc.hasnativeorder():
- raise util.Abort(_('--sourcesort is not supported by this data source'))
-
- fmap = opts.get('filemap')
- if fmap:
- srcc = filemap.filemap_source(ui, srcc, fmap)
- destc.setfilemapmode(True)
-
- if not revmapfile:
- try:
- revmapfile = destc.revmapfile()
- except:
- revmapfile = os.path.join(destc, "map")
-
- c = converter(ui, srcc, destc, revmapfile, opts)
- c.convert(sortmode)
-
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.pyo
deleted file mode 100644
index 15f040a..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/convcmd.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.py
deleted file mode 100644
index 501fae2..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# cvs.py: CVS conversion code inspired by hg-cvs-import and git-cvsimport
-#
-# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import os, re, socket, errno
-from cStringIO import StringIO
-from mercurial import encoding, util
-from mercurial.i18n import _
-
-from common import NoRepo, commit, converter_source, checktool
-import cvsps
-
-class convert_cvs(converter_source):
- def __init__(self, ui, path, rev=None):
- super(convert_cvs, self).__init__(ui, path, rev=rev)
-
- cvs = os.path.join(path, "CVS")
- if not os.path.exists(cvs):
- raise NoRepo(_("%s does not look like a CVS checkout") % path)
-
- checktool('cvs')
-
- self.changeset = None
- self.files = {}
- self.tags = {}
- self.lastbranch = {}
- self.socket = None
- self.cvsroot = open(os.path.join(cvs, "Root")).read()[:-1]
- self.cvsrepo = open(os.path.join(cvs, "Repository")).read()[:-1]
- self.encoding = encoding.encoding
-
- self._connect()
-
- def _parse(self):
- if self.changeset is not None:
- return
- self.changeset = {}
-
- maxrev = 0
- if self.rev:
- # TODO: handle tags
- try:
- # patchset number?
- maxrev = int(self.rev)
- except ValueError:
- raise util.Abort(_('revision %s is not a patchset number')
- % self.rev)
-
- d = os.getcwd()
- try:
- os.chdir(self.path)
- id = None
-
- cache = 'update'
- if not self.ui.configbool('convert', 'cvsps.cache', True):
- cache = None
- db = cvsps.createlog(self.ui, cache=cache)
- db = cvsps.createchangeset(self.ui, db,
- fuzz=int(self.ui.config('convert', 'cvsps.fuzz', 60)),
- mergeto=self.ui.config('convert', 'cvsps.mergeto', None),
- mergefrom=self.ui.config('convert', 'cvsps.mergefrom', None))
-
- for cs in db:
- if maxrev and cs.id > maxrev:
- break
- id = str(cs.id)
- cs.author = self.recode(cs.author)
- self.lastbranch[cs.branch] = id
- cs.comment = self.recode(cs.comment)
- date = util.datestr(cs.date)
- self.tags.update(dict.fromkeys(cs.tags, id))
-
- files = {}
- for f in cs.entries:
- files[f.file] = "%s%s" % ('.'.join([str(x)
- for x in f.revision]),
- ['', '(DEAD)'][f.dead])
-
- # add current commit to set
- c = commit(author=cs.author, date=date,
- parents=[str(p.id) for p in cs.parents],
- desc=cs.comment, branch=cs.branch or '')
- self.changeset[id] = c
- self.files[id] = files
-
- self.heads = self.lastbranch.values()
- finally:
- os.chdir(d)
-
- def _connect(self):
- root = self.cvsroot
- conntype = None
- user, host = None, None
- cmd = ['cvs', 'server']
-
- self.ui.status(_("connecting to %s\n") % root)
-
- if root.startswith(":pserver:"):
- root = root[9:]
- m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)',
- root)
- if m:
- conntype = "pserver"
- user, passw, serv, port, root = m.groups()
- if not user:
- user = "anonymous"
- if not port:
- port = 2401
- else:
- port = int(port)
- format0 = ":pserver:%s@%s:%s" % (user, serv, root)
- format1 = ":pserver:%s@%s:%d%s" % (user, serv, port, root)
-
- if not passw:
- passw = "A"
- cvspass = os.path.expanduser("~/.cvspass")
- try:
- pf = open(cvspass)
- for line in pf.read().splitlines():
- part1, part2 = line.split(' ', 1)
- if part1 == '/1':
- # /1 :pserver:user@example.com:2401/cvsroot/foo Ah<Z
- part1, part2 = part2.split(' ', 1)
- format = format1
- else:
- # :pserver:user@example.com:/cvsroot/foo Ah<Z
- format = format0
- if part1 == format:
- passw = part2
- break
- pf.close()
- except IOError, inst:
- if inst.errno != errno.ENOENT:
- if not getattr(inst, 'filename', None):
- inst.filename = cvspass
- raise
-
- sck = socket.socket()
- sck.connect((serv, port))
- sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw,
- "END AUTH REQUEST", ""]))
- if sck.recv(128) != "I LOVE YOU\n":
- raise util.Abort(_("CVS pserver authentication failed"))
-
- self.writep = self.readp = sck.makefile('r+')
-
- if not conntype and root.startswith(":local:"):
- conntype = "local"
- root = root[7:]
-
- if not conntype:
- # :ext:user@host/home/user/path/to/cvsroot
- if root.startswith(":ext:"):
- root = root[5:]
- m = re.match(r'(?:([^@:/]+)@)?([^:/]+):?(.*)', root)
- # Do not take Windows path "c:\foo\bar" for a connection strings
- if os.path.isdir(root) or not m:
- conntype = "local"
- else:
- conntype = "rsh"
- user, host, root = m.group(1), m.group(2), m.group(3)
-
- if conntype != "pserver":
- if conntype == "rsh":
- rsh = os.environ.get("CVS_RSH") or "ssh"
- if user:
- cmd = [rsh, '-l', user, host] + cmd
- else:
- cmd = [rsh, host] + cmd
-
- # popen2 does not support argument lists under Windows
- cmd = [util.shellquote(arg) for arg in cmd]
- cmd = util.quotecommand(' '.join(cmd))
- self.writep, self.readp = util.popen2(cmd)
-
- self.realroot = root
-
- self.writep.write("Root %s\n" % root)
- self.writep.write("Valid-responses ok error Valid-requests Mode"
- " M Mbinary E Checked-in Created Updated"
- " Merged Removed\n")
- self.writep.write("valid-requests\n")
- self.writep.flush()
- r = self.readp.readline()
- if not r.startswith("Valid-requests"):
- raise util.Abort(_('unexpected response from CVS server '
- '(expected "Valid-requests", but got %r)')
- % r)
- if "UseUnchanged" in r:
- self.writep.write("UseUnchanged\n")
- self.writep.flush()
- r = self.readp.readline()
-
- def getheads(self):
- self._parse()
- return self.heads
-
- def getfile(self, name, rev):
-
- def chunkedread(fp, count):
- # file-objects returned by socked.makefile() do not handle
- # large read() requests very well.
- chunksize = 65536
- output = StringIO()
- while count > 0:
- data = fp.read(min(count, chunksize))
- if not data:
- raise util.Abort(_("%d bytes missing from remote file")
- % count)
- count -= len(data)
- output.write(data)
- return output.getvalue()
-
- self._parse()
- if rev.endswith("(DEAD)"):
- raise IOError
-
- args = ("-N -P -kk -r %s --" % rev).split()
- args.append(self.cvsrepo + '/' + name)
- for x in args:
- self.writep.write("Argument %s\n" % x)
- self.writep.write("Directory .\n%s\nco\n" % self.realroot)
- self.writep.flush()
-
- data = ""
- mode = None
- while 1:
- line = self.readp.readline()
- if line.startswith("Created ") or line.startswith("Updated "):
- self.readp.readline() # path
- self.readp.readline() # entries
- mode = self.readp.readline()[:-1]
- count = int(self.readp.readline()[:-1])
- data = chunkedread(self.readp, count)
- elif line.startswith(" "):
- data += line[1:]
- elif line.startswith("M "):
- pass
- elif line.startswith("Mbinary "):
- count = int(self.readp.readline()[:-1])
- data = chunkedread(self.readp, count)
- else:
- if line == "ok\n":
- if mode is None:
- raise util.Abort(_('malformed response from CVS'))
- return (data, "x" in mode and "x" or "")
- elif line.startswith("E "):
- self.ui.warn(_("cvs server: %s\n") % line[2:])
- elif line.startswith("Remove"):
- self.readp.readline()
- else:
- raise util.Abort(_("unknown CVS response: %s") % line)
-
- def getchanges(self, rev):
- self._parse()
- return sorted(self.files[rev].iteritems()), {}
-
- def getcommit(self, rev):
- self._parse()
- return self.changeset[rev]
-
- def gettags(self):
- self._parse()
- return self.tags
-
- def getchangedfiles(self, rev, i):
- self._parse()
- return sorted(self.files[rev])
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.pyo
deleted file mode 100644
index d73fe3f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvs.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.py
deleted file mode 100644
index 1519d41..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.py
+++ /dev/null
@@ -1,847 +0,0 @@
-# Mercurial built-in replacement for cvsps.
-#
-# Copyright 2008, Frank Kingswood <frank@kingswood-consulting.co.uk>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import os
-import re
-import cPickle as pickle
-from mercurial import util
-from mercurial.i18n import _
-from mercurial import hook
-
-class logentry(object):
- '''Class logentry has the following attributes:
- .author - author name as CVS knows it
- .branch - name of branch this revision is on
- .branches - revision tuple of branches starting at this revision
- .comment - commit message
- .date - the commit date as a (time, tz) tuple
- .dead - true if file revision is dead
- .file - Name of file
- .lines - a tuple (+lines, -lines) or None
- .parent - Previous revision of this entry
- .rcs - name of file as returned from CVS
- .revision - revision number as tuple
- .tags - list of tags on the file
- .synthetic - is this a synthetic "file ... added on ..." revision?
- .mergepoint- the branch that has been merged from
- (if present in rlog output)
- .branchpoints- the branches that start at the current entry
- '''
- def __init__(self, **entries):
- self.synthetic = False
- self.__dict__.update(entries)
-
- def __repr__(self):
- return "<%s at 0x%x: %s %s>" % (self.__class__.__name__,
- id(self),
- self.file,
- ".".join(map(str, self.revision)))
-
-class logerror(Exception):
- pass
-
-def getrepopath(cvspath):
- """Return the repository path from a CVS path.
-
- >>> getrepopath('/foo/bar')
- '/foo/bar'
- >>> getrepopath('c:/foo/bar')
- 'c:/foo/bar'
- >>> getrepopath(':pserver:10/foo/bar')
- '/foo/bar'
- >>> getrepopath(':pserver:10c:/foo/bar')
- '/foo/bar'
- >>> getrepopath(':pserver:/foo/bar')
- '/foo/bar'
- >>> getrepopath(':pserver:c:/foo/bar')
- 'c:/foo/bar'
- >>> getrepopath(':pserver:truc@foo.bar:/foo/bar')
- '/foo/bar'
- >>> getrepopath(':pserver:truc@foo.bar:c:/foo/bar')
- 'c:/foo/bar'
- """
- # According to CVS manual, CVS paths are expressed like:
- # [:method:][[user][:password]@]hostname[:[port]]/path/to/repository
- #
- # Unfortunately, Windows absolute paths start with a drive letter
- # like 'c:' making it harder to parse. Here we assume that drive
- # letters are only one character long and any CVS component before
- # the repository path is at least 2 characters long, and use this
- # to disambiguate.
- parts = cvspath.split(':')
- if len(parts) == 1:
- return parts[0]
- # Here there is an ambiguous case if we have a port number
- # immediately followed by a Windows driver letter. We assume this
- # never happens and decide it must be CVS path component,
- # therefore ignoring it.
- if len(parts[-2]) > 1:
- return parts[-1].lstrip('0123456789')
- return parts[-2] + ':' + parts[-1]
-
-def createlog(ui, directory=None, root="", rlog=True, cache=None):
- '''Collect the CVS rlog'''
-
- # Because we store many duplicate commit log messages, reusing strings
- # saves a lot of memory and pickle storage space.
- _scache = {}
- def scache(s):
- "return a shared version of a string"
- return _scache.setdefault(s, s)
-
- ui.status(_('collecting CVS rlog\n'))
-
- log = [] # list of logentry objects containing the CVS state
-
- # patterns to match in CVS (r)log output, by state of use
- re_00 = re.compile('RCS file: (.+)$')
- re_01 = re.compile('cvs \\[r?log aborted\\]: (.+)$')
- re_02 = re.compile('cvs (r?log|server): (.+)\n$')
- re_03 = re.compile("(Cannot access.+CVSROOT)|"
- "(can't create temporary directory.+)$")
- re_10 = re.compile('Working file: (.+)$')
- re_20 = re.compile('symbolic names:')
- re_30 = re.compile('\t(.+): ([\\d.]+)$')
- re_31 = re.compile('----------------------------$')
- re_32 = re.compile('======================================='
- '======================================$')
- re_50 = re.compile('revision ([\\d.]+)(\s+locked by:\s+.+;)?$')
- re_60 = re.compile(r'date:\s+(.+);\s+author:\s+(.+);\s+state:\s+(.+?);'
- r'(\s+lines:\s+(\+\d+)?\s+(-\d+)?;)?'
- r'(.*mergepoint:\s+([^;]+);)?')
- re_70 = re.compile('branches: (.+);$')
-
- file_added_re = re.compile(r'file [^/]+ was (initially )?added on branch')
-
- prefix = '' # leading path to strip of what we get from CVS
-
- if directory is None:
- # Current working directory
-
- # Get the real directory in the repository
- try:
- prefix = open(os.path.join('CVS','Repository')).read().strip()
- directory = prefix
- if prefix == ".":
- prefix = ""
- except IOError:
- raise logerror(_('not a CVS sandbox'))
-
- if prefix and not prefix.endswith(os.sep):
- prefix += os.sep
-
- # Use the Root file in the sandbox, if it exists
- try:
- root = open(os.path.join('CVS','Root')).read().strip()
- except IOError:
- pass
-
- if not root:
- root = os.environ.get('CVSROOT', '')
-
- # read log cache if one exists
- oldlog = []
- date = None
-
- if cache:
- cachedir = os.path.expanduser('~/.hg.cvsps')
- if not os.path.exists(cachedir):
- os.mkdir(cachedir)
-
- # The cvsps cache pickle needs a uniquified name, based on the
- # repository location. The address may have all sort of nasties
- # in it, slashes, colons and such. So here we take just the
- # alphanumerics, concatenated in a way that does not mix up the
- # various components, so that
- # :pserver:user@server:/path
- # and
- # /pserver/user/server/path
- # are mapped to different cache file names.
- cachefile = root.split(":") + [directory, "cache"]
- cachefile = ['-'.join(re.findall(r'\w+', s)) for s in cachefile if s]
- cachefile = os.path.join(cachedir,
- '.'.join([s for s in cachefile if s]))
-
- if cache == 'update':
- try:
- ui.note(_('reading cvs log cache %s\n') % cachefile)
- oldlog = pickle.load(open(cachefile))
- ui.note(_('cache has %d log entries\n') % len(oldlog))
- except Exception, e:
- ui.note(_('error reading cache: %r\n') % e)
-
- if oldlog:
- date = oldlog[-1].date # last commit date as a (time,tz) tuple
- date = util.datestr(date, '%Y/%m/%d %H:%M:%S %1%2')
-
- # build the CVS commandline
- cmd = ['cvs', '-q']
- if root:
- cmd.append('-d%s' % root)
- p = util.normpath(getrepopath(root))
- if not p.endswith('/'):
- p += '/'
- if prefix:
- # looks like normpath replaces "" by "."
- prefix = p + util.normpath(prefix)
- else:
- prefix = p
- cmd.append(['log', 'rlog'][rlog])
- if date:
- # no space between option and date string
- cmd.append('-d>%s' % date)
- cmd.append(directory)
-
- # state machine begins here
- tags = {} # dictionary of revisions on current file with their tags
- branchmap = {} # mapping between branch names and revision numbers
- state = 0
- store = False # set when a new record can be appended
-
- cmd = [util.shellquote(arg) for arg in cmd]
- ui.note(_("running %s\n") % (' '.join(cmd)))
- ui.debug("prefix=%r directory=%r root=%r\n" % (prefix, directory, root))
-
- pfp = util.popen(' '.join(cmd))
- peek = pfp.readline()
- while True:
- line = peek
- if line == '':
- break
- peek = pfp.readline()
- if line.endswith('\n'):
- line = line[:-1]
- #ui.debug('state=%d line=%r\n' % (state, line))
-
- if state == 0:
- # initial state, consume input until we see 'RCS file'
- match = re_00.match(line)
- if match:
- rcs = match.group(1)
- tags = {}
- if rlog:
- filename = util.normpath(rcs[:-2])
- if filename.startswith(prefix):
- filename = filename[len(prefix):]
- if filename.startswith('/'):
- filename = filename[1:]
- if filename.startswith('Attic/'):
- filename = filename[6:]
- else:
- filename = filename.replace('/Attic/', '/')
- state = 2
- continue
- state = 1
- continue
- match = re_01.match(line)
- if match:
- raise logerror(match.group(1))
- match = re_02.match(line)
- if match:
- raise logerror(match.group(2))
- if re_03.match(line):
- raise logerror(line)
-
- elif state == 1:
- # expect 'Working file' (only when using log instead of rlog)
- match = re_10.match(line)
- assert match, _('RCS file must be followed by working file')
- filename = util.normpath(match.group(1))
- state = 2
-
- elif state == 2:
- # expect 'symbolic names'
- if re_20.match(line):
- branchmap = {}
- state = 3
-
- elif state == 3:
- # read the symbolic names and store as tags
- match = re_30.match(line)
- if match:
- rev = [int(x) for x in match.group(2).split('.')]
-
- # Convert magic branch number to an odd-numbered one
- revn = len(rev)
- if revn > 3 and (revn % 2) == 0 and rev[-2] == 0:
- rev = rev[:-2] + rev[-1:]
- rev = tuple(rev)
-
- if rev not in tags:
- tags[rev] = []
- tags[rev].append(match.group(1))
- branchmap[match.group(1)] = match.group(2)
-
- elif re_31.match(line):
- state = 5
- elif re_32.match(line):
- state = 0
-
- elif state == 4:
- # expecting '------' separator before first revision
- if re_31.match(line):
- state = 5
- else:
- assert not re_32.match(line), _('must have at least '
- 'some revisions')
-
- elif state == 5:
- # expecting revision number and possibly (ignored) lock indication
- # we create the logentry here from values stored in states 0 to 4,
- # as this state is re-entered for subsequent revisions of a file.
- match = re_50.match(line)
- assert match, _('expected revision number')
- e = logentry(rcs=scache(rcs), file=scache(filename),
- revision=tuple([int(x) for x in match.group(1).split('.')]),
- branches=[], parent=None)
- state = 6
-
- elif state == 6:
- # expecting date, author, state, lines changed
- match = re_60.match(line)
- assert match, _('revision must be followed by date line')
- d = match.group(1)
- if d[2] == '/':
- # Y2K
- d = '19' + d
-
- if len(d.split()) != 3:
- # cvs log dates always in GMT
- d = d + ' UTC'
- e.date = util.parsedate(d, ['%y/%m/%d %H:%M:%S',
- '%Y/%m/%d %H:%M:%S',
- '%Y-%m-%d %H:%M:%S'])
- e.author = scache(match.group(2))
- e.dead = match.group(3).lower() == 'dead'
-
- if match.group(5):
- if match.group(6):
- e.lines = (int(match.group(5)), int(match.group(6)))
- else:
- e.lines = (int(match.group(5)), 0)
- elif match.group(6):
- e.lines = (0, int(match.group(6)))
- else:
- e.lines = None
-
- if match.group(7): # cvsnt mergepoint
- myrev = match.group(8).split('.')
- if len(myrev) == 2: # head
- e.mergepoint = 'HEAD'
- else:
- myrev = '.'.join(myrev[:-2] + ['0', myrev[-2]])
- branches = [b for b in branchmap if branchmap[b] == myrev]
- assert len(branches) == 1, 'unknown branch: %s' % e.mergepoint
- e.mergepoint = branches[0]
- else:
- e.mergepoint = None
- e.comment = []
- state = 7
-
- elif state == 7:
- # read the revision numbers of branches that start at this revision
- # or store the commit log message otherwise
- m = re_70.match(line)
- if m:
- e.branches = [tuple([int(y) for y in x.strip().split('.')])
- for x in m.group(1).split(';')]
- state = 8
- elif re_31.match(line) and re_50.match(peek):
- state = 5
- store = True
- elif re_32.match(line):
- state = 0
- store = True
- else:
- e.comment.append(line)
-
- elif state == 8:
- # store commit log message
- if re_31.match(line):
- state = 5
- store = True
- elif re_32.match(line):
- state = 0
- store = True
- else:
- e.comment.append(line)
-
- # When a file is added on a branch B1, CVS creates a synthetic
- # dead trunk revision 1.1 so that the branch has a root.
- # Likewise, if you merge such a file to a later branch B2 (one
- # that already existed when the file was added on B1), CVS
- # creates a synthetic dead revision 1.1.x.1 on B2. Don't drop
- # these revisions now, but mark them synthetic so
- # createchangeset() can take care of them.
- if (store and
- e.dead and
- e.revision[-1] == 1 and # 1.1 or 1.1.x.1
- len(e.comment) == 1 and
- file_added_re.match(e.comment[0])):
- ui.debug('found synthetic revision in %s: %r\n'
- % (e.rcs, e.comment[0]))
- e.synthetic = True
-
- if store:
- # clean up the results and save in the log.
- store = False
- e.tags = sorted([scache(x) for x in tags.get(e.revision, [])])
- e.comment = scache('\n'.join(e.comment))
-
- revn = len(e.revision)
- if revn > 3 and (revn % 2) == 0:
- e.branch = tags.get(e.revision[:-1], [None])[0]
- else:
- e.branch = None
-
- # find the branches starting from this revision
- branchpoints = set()
- for branch, revision in branchmap.iteritems():
- revparts = tuple([int(i) for i in revision.split('.')])
- if len(revparts) < 2: # bad tags
- continue
- if revparts[-2] == 0 and revparts[-1] % 2 == 0:
- # normal branch
- if revparts[:-2] == e.revision:
- branchpoints.add(branch)
- elif revparts == (1, 1, 1): # vendor branch
- if revparts in e.branches:
- branchpoints.add(branch)
- e.branchpoints = branchpoints
-
- log.append(e)
-
- if len(log) % 100 == 0:
- ui.status(util.ellipsis('%d %s' % (len(log), e.file), 80)+'\n')
-
- log.sort(key=lambda x: (x.rcs, x.revision))
-
- # find parent revisions of individual files
- versions = {}
- for e in log:
- branch = e.revision[:-1]
- p = versions.get((e.rcs, branch), None)
- if p is None:
- p = e.revision[:-2]
- e.parent = p
- versions[(e.rcs, branch)] = e.revision
-
- # update the log cache
- if cache:
- if log:
- # join up the old and new logs
- log.sort(key=lambda x: x.date)
-
- if oldlog and oldlog[-1].date >= log[0].date:
- raise logerror(_('log cache overlaps with new log entries,'
- ' re-run without cache.'))
-
- log = oldlog + log
-
- # write the new cachefile
- ui.note(_('writing cvs log cache %s\n') % cachefile)
- pickle.dump(log, open(cachefile, 'w'))
- else:
- log = oldlog
-
- ui.status(_('%d log entries\n') % len(log))
-
- hook.hook(ui, None, "cvslog", True, log=log)
-
- return log
-
-
-class changeset(object):
- '''Class changeset has the following attributes:
- .id - integer identifying this changeset (list index)
- .author - author name as CVS knows it
- .branch - name of branch this changeset is on, or None
- .comment - commit message
- .date - the commit date as a (time,tz) tuple
- .entries - list of logentry objects in this changeset
- .parents - list of one or two parent changesets
- .tags - list of tags on this changeset
- .synthetic - from synthetic revision "file ... added on branch ..."
- .mergepoint- the branch that has been merged from
- (if present in rlog output)
- .branchpoints- the branches that start at the current entry
- '''
- def __init__(self, **entries):
- self.synthetic = False
- self.__dict__.update(entries)
-
- def __repr__(self):
- return "<%s at 0x%x: %s>" % (self.__class__.__name__,
- id(self),
- getattr(self, 'id', "(no id)"))
-
-def createchangeset(ui, log, fuzz=60, mergefrom=None, mergeto=None):
- '''Convert log into changesets.'''
-
- ui.status(_('creating changesets\n'))
-
- # Merge changesets
-
- log.sort(key=lambda x: (x.comment, x.author, x.branch, x.date))
-
- changesets = []
- files = set()
- c = None
- for i, e in enumerate(log):
-
- # Check if log entry belongs to the current changeset or not.
-
- # Since CVS is file centric, two different file revisions with
- # different branchpoints should be treated as belonging to two
- # different changesets (and the ordering is important and not
- # honoured by cvsps at this point).
- #
- # Consider the following case:
- # foo 1.1 branchpoints: [MYBRANCH]
- # bar 1.1 branchpoints: [MYBRANCH, MYBRANCH2]
- #
- # Here foo is part only of MYBRANCH, but not MYBRANCH2, e.g. a
- # later version of foo may be in MYBRANCH2, so foo should be the
- # first changeset and bar the next and MYBRANCH and MYBRANCH2
- # should both start off of the bar changeset. No provisions are
- # made to ensure that this is, in fact, what happens.
- if not (c and
- e.comment == c.comment and
- e.author == c.author and
- e.branch == c.branch and
- (not hasattr(e, 'branchpoints') or
- not hasattr (c, 'branchpoints') or
- e.branchpoints == c.branchpoints) and
- ((c.date[0] + c.date[1]) <=
- (e.date[0] + e.date[1]) <=
- (c.date[0] + c.date[1]) + fuzz) and
- e.file not in files):
- c = changeset(comment=e.comment, author=e.author,
- branch=e.branch, date=e.date, entries=[],
- mergepoint=getattr(e, 'mergepoint', None),
- branchpoints=getattr(e, 'branchpoints', set()))
- changesets.append(c)
- files = set()
- if len(changesets) % 100 == 0:
- t = '%d %s' % (len(changesets), repr(e.comment)[1:-1])
- ui.status(util.ellipsis(t, 80) + '\n')
-
- c.entries.append(e)
- files.add(e.file)
- c.date = e.date # changeset date is date of latest commit in it
-
- # Mark synthetic changesets
-
- for c in changesets:
- # Synthetic revisions always get their own changeset, because
- # the log message includes the filename. E.g. if you add file3
- # and file4 on a branch, you get four log entries and three
- # changesets:
- # "File file3 was added on branch ..." (synthetic, 1 entry)
- # "File file4 was added on branch ..." (synthetic, 1 entry)
- # "Add file3 and file4 to fix ..." (real, 2 entries)
- # Hence the check for 1 entry here.
- c.synthetic = len(c.entries) == 1 and c.entries[0].synthetic
-
- # Sort files in each changeset
-
- for c in changesets:
- def pathcompare(l, r):
- 'Mimic cvsps sorting order'
- l = l.split('/')
- r = r.split('/')
- nl = len(l)
- nr = len(r)
- n = min(nl, nr)
- for i in range(n):
- if i + 1 == nl and nl < nr:
- return -1
- elif i + 1 == nr and nl > nr:
- return +1
- elif l[i] < r[i]:
- return -1
- elif l[i] > r[i]:
- return +1
- return 0
- def entitycompare(l, r):
- return pathcompare(l.file, r.file)
-
- c.entries.sort(entitycompare)
-
- # Sort changesets by date
-
- def cscmp(l, r):
- d = sum(l.date) - sum(r.date)
- if d:
- return d
-
- # detect vendor branches and initial commits on a branch
- le = {}
- for e in l.entries:
- le[e.rcs] = e.revision
- re = {}
- for e in r.entries:
- re[e.rcs] = e.revision
-
- d = 0
- for e in l.entries:
- if re.get(e.rcs, None) == e.parent:
- assert not d
- d = 1
- break
-
- for e in r.entries:
- if le.get(e.rcs, None) == e.parent:
- assert not d
- d = -1
- break
-
- return d
-
- changesets.sort(cscmp)
-
- # Collect tags
-
- globaltags = {}
- for c in changesets:
- for e in c.entries:
- for tag in e.tags:
- # remember which is the latest changeset to have this tag
- globaltags[tag] = c
-
- for c in changesets:
- tags = set()
- for e in c.entries:
- tags.update(e.tags)
- # remember tags only if this is the latest changeset to have it
- c.tags = sorted(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
- # {{mergefrombranch BRANCHNAME}} by setting two parents.
-
- if mergeto is None:
- mergeto = r'{{mergetobranch ([-\w]+)}}'
- if mergeto:
- mergeto = re.compile(mergeto)
-
- if mergefrom is None:
- mergefrom = r'{{mergefrombranch ([-\w]+)}}'
- if mergefrom:
- mergefrom = re.compile(mergefrom)
-
- versions = {} # changeset index where we saw any particular file version
- branches = {} # changeset index where we saw a branch
- n = len(changesets)
- i = 0
- while i < n:
- c = changesets[i]
-
- for f in c.entries:
- versions[(f.rcs, f.revision)] = i
-
- p = None
- if c.branch in branches:
- p = branches[c.branch]
- else:
- # first changeset on a new branch
- # the parent is a changeset with the branch in its
- # branchpoints such that it is the latest possible
- # commit without any intervening, unrelated commits.
-
- for candidate in xrange(i):
- if c.branch not in changesets[candidate].branchpoints:
- if p is not None:
- break
- continue
- p = candidate
-
- c.parents = []
- if p is not None:
- p = changesets[p]
-
- # Ensure no changeset has a synthetic changeset as a parent.
- while p.synthetic:
- assert len(p.parents) <= 1, \
- _('synthetic changeset cannot have multiple parents')
- if p.parents:
- p = p.parents[0]
- else:
- p = None
- break
-
- if p is not None:
- c.parents.append(p)
-
- if c.mergepoint:
- if c.mergepoint == 'HEAD':
- c.mergepoint = None
- c.parents.append(changesets[branches[c.mergepoint]])
-
- if mergefrom:
- m = mergefrom.search(c.comment)
- if m:
- m = m.group(1)
- if m == 'HEAD':
- m = None
- try:
- candidate = changesets[branches[m]]
- except KeyError:
- ui.warn(_("warning: CVS commit message references "
- "non-existent branch %r:\n%s\n")
- % (m, c.comment))
- if m in branches and c.branch != m and not candidate.synthetic:
- c.parents.append(candidate)
-
- if mergeto:
- m = mergeto.search(c.comment)
- if m:
- try:
- m = m.group(1)
- if m == 'HEAD':
- m = None
- except:
- m = None # if no group found then merge to HEAD
- if m in branches and c.branch != m:
- # insert empty changeset for merge
- cc = changeset(
- author=c.author, branch=m, date=c.date,
- comment='convert-repo: CVS merge from branch %s'
- % c.branch,
- entries=[], tags=[],
- parents=[changesets[branches[m]], c])
- changesets.insert(i + 1, cc)
- branches[m] = i + 1
-
- # adjust our loop counters now we have inserted a new entry
- n += 1
- i += 2
- continue
-
- branches[c.branch] = i
- i += 1
-
- # Drop synthetic changesets (safe now that we have ensured no other
- # changesets can have them as parents).
- i = 0
- while i < len(changesets):
- if changesets[i].synthetic:
- del changesets[i]
- else:
- i += 1
-
- # Number changesets
-
- for i, c in enumerate(changesets):
- c.id = i + 1
-
- ui.status(_('%d changeset entries\n') % len(changesets))
-
- hook.hook(ui, None, "cvschangesets", True, changesets=changesets)
-
- return changesets
-
-
-def debugcvsps(ui, *args, **opts):
- '''Read CVS rlog for current directory or named path in
- repository, and convert the log to changesets based on matching
- commit log entries and dates.
- '''
- if opts["new_cache"]:
- cache = "write"
- elif opts["update_cache"]:
- cache = "update"
- else:
- cache = None
-
- revisions = opts["revisions"]
-
- try:
- if args:
- log = []
- for d in args:
- log += createlog(ui, d, root=opts["root"], cache=cache)
- else:
- log = createlog(ui, root=opts["root"], cache=cache)
- except logerror, e:
- ui.write("%r\n"%e)
- return
-
- changesets = createchangeset(ui, log, opts["fuzz"])
- del log
-
- # Print changesets (optionally filtered)
-
- off = len(revisions)
- branches = {} # latest version number in each branch
- ancestors = {} # parent branch
- for cs in changesets:
-
- if opts["ancestors"]:
- if cs.branch not in branches and cs.parents and cs.parents[0].id:
- ancestors[cs.branch] = (changesets[cs.parents[0].id - 1].branch,
- cs.parents[0].id)
- branches[cs.branch] = cs.id
-
- # limit by branches
- if opts["branches"] and (cs.branch or 'HEAD') not in opts["branches"]:
- continue
-
- if not off:
- # Note: trailing spaces on several lines here are needed to have
- # bug-for-bug compatibility with cvsps.
- ui.write('---------------------\n')
- ui.write('PatchSet %d \n' % cs.id)
- ui.write('Date: %s\n' % util.datestr(cs.date,
- '%Y/%m/%d %H:%M:%S %1%2'))
- ui.write('Author: %s\n' % cs.author)
- ui.write('Branch: %s\n' % (cs.branch or 'HEAD'))
- ui.write('Tag%s: %s \n' % (['', 's'][len(cs.tags) > 1],
- ','.join(cs.tags) or '(none)'))
- branchpoints = getattr(cs, 'branchpoints', None)
- if branchpoints:
- ui.write('Branchpoints: %s \n' % ', '.join(branchpoints))
- if opts["parents"] and cs.parents:
- if len(cs.parents) > 1:
- ui.write('Parents: %s\n' %
- (','.join([str(p.id) for p in cs.parents])))
- else:
- ui.write('Parent: %d\n' % cs.parents[0].id)
-
- if opts["ancestors"]:
- b = cs.branch
- r = []
- while b:
- b, c = ancestors[b]
- r.append('%s:%d:%d' % (b or "HEAD", c, branches[b]))
- if r:
- ui.write('Ancestors: %s\n' % (','.join(r)))
-
- ui.write('Log:\n')
- ui.write('%s\n\n' % cs.comment)
- ui.write('Members: \n')
- for f in cs.entries:
- fn = f.file
- if fn.startswith(opts["prefix"]):
- fn = fn[len(opts["prefix"]):]
- ui.write('\t%s:%s->%s%s \n' % (
- fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL',
- '.'.join([str(x) for x in f.revision]),
- ['', '(DEAD)'][f.dead]))
- ui.write('\n')
-
- # have we seen the start tag?
- if revisions and off:
- if revisions[0] == str(cs.id) or \
- revisions[0] in cs.tags:
- off = False
-
- # see if we reached the end tag
- if len(revisions) > 1 and not off:
- if revisions[1] == str(cs.id) or \
- revisions[1] in cs.tags:
- break
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.pyo
deleted file mode 100644
index fdf6d44..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/cvsps.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.py
deleted file mode 100644
index 9863eb8..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# darcs.py - darcs support for the convert extension
-#
-# Copyright 2007-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from common import NoRepo, checktool, commandline, commit, converter_source
-from mercurial.i18n import _
-from mercurial import encoding, util
-import os, shutil, tempfile, re
-
-# The naming drift of ElementTree is fun!
-
-try:
- from xml.etree.cElementTree import ElementTree, XMLParser
-except ImportError:
- try:
- from xml.etree.ElementTree import ElementTree, XMLParser
- except ImportError:
- try:
- from elementtree.cElementTree import ElementTree, XMLParser
- except ImportError:
- try:
- from elementtree.ElementTree import ElementTree, XMLParser
- except ImportError:
- ElementTree = None
-
-class darcs_source(converter_source, commandline):
- def __init__(self, ui, path, rev=None):
- converter_source.__init__(self, ui, path, rev=rev)
- commandline.__init__(self, ui, 'darcs')
-
- # check for _darcs, ElementTree so that we can easily skip
- # test-convert-darcs if ElementTree is not around
- if not os.path.exists(os.path.join(path, '_darcs')):
- raise NoRepo(_("%s does not look like a darcs repository") % path)
-
- checktool('darcs')
- version = self.run0('--version').splitlines()[0].strip()
- if version < '2.1':
- raise util.Abort(_('darcs version 2.1 or newer needed (found %r)') %
- version)
-
- if ElementTree is None:
- raise util.Abort(_("Python ElementTree module is not available"))
-
- self.path = os.path.realpath(path)
-
- self.lastrev = None
- self.changes = {}
- self.parents = {}
- self.tags = {}
-
- # Check darcs repository format
- format = self.format()
- if format:
- if format in ('darcs-1.0', 'hashed'):
- raise NoRepo(_("%s repository format is unsupported, "
- "please upgrade") % format)
- else:
- self.ui.warn(_('failed to detect repository format!'))
-
- def before(self):
- self.tmppath = tempfile.mkdtemp(
- prefix='convert-' + os.path.basename(self.path) + '-')
- output, status = self.run('init', repodir=self.tmppath)
- self.checkexit(status)
-
- tree = self.xml('changes', xml_output=True, summary=True,
- repodir=self.path)
- tagname = None
- child = None
- for elt in tree.findall('patch'):
- node = elt.get('hash')
- name = elt.findtext('name', '')
- if name.startswith('TAG '):
- tagname = name[4:].strip()
- elif tagname is not None:
- self.tags[tagname] = node
- tagname = None
- self.changes[node] = elt
- self.parents[child] = [node]
- child = node
- self.parents[child] = []
-
- def after(self):
- self.ui.debug('cleaning up %s\n' % self.tmppath)
- shutil.rmtree(self.tmppath, ignore_errors=True)
-
- def recode(self, s, encoding=None):
- if isinstance(s, unicode):
- # XMLParser returns unicode objects for anything it can't
- # encode into ASCII. We convert them back to str to get
- # recode's normal conversion behavior.
- s = s.encode('latin-1')
- return super(darcs_source, self).recode(s, encoding)
-
- def xml(self, cmd, **kwargs):
- # NOTE: darcs is currently encoding agnostic and will print
- # patch metadata byte-for-byte, even in the XML changelog.
- etree = ElementTree()
- # While we are decoding the XML as latin-1 to be as liberal as
- # possible, etree will still raise an exception if any
- # non-printable characters are in the XML changelog.
- parser = XMLParser(encoding='latin-1')
- fp = self._run(cmd, **kwargs)
- etree.parse(fp, parser=parser)
- self.checkexit(fp.close())
- return etree.getroot()
-
- def format(self):
- output, status = self.run('show', 'repo', no_files=True,
- repodir=self.path)
- self.checkexit(status)
- m = re.search(r'^\s*Format:\s*(.*)$', output, re.MULTILINE)
- if not m:
- return None
- return ','.join(sorted(f.strip() for f in m.group(1).split(',')))
-
- def manifest(self):
- man = []
- output, status = self.run('show', 'files', no_directories=True,
- repodir=self.tmppath)
- self.checkexit(status)
- for line in output.split('\n'):
- path = line[2:]
- if path:
- man.append(path)
- return man
-
- def getheads(self):
- return self.parents[None]
-
- def getcommit(self, rev):
- elt = self.changes[rev]
- date = util.strdate(elt.get('local_date'), '%a %b %d %H:%M:%S %Z %Y')
- desc = elt.findtext('name') + '\n' + elt.findtext('comment', '')
- # etree can return unicode objects for name, comment, and author,
- # so recode() is used to ensure str objects are emitted.
- return commit(author=self.recode(elt.get('author')),
- date=util.datestr(date),
- desc=self.recode(desc).strip(),
- parents=self.parents[rev])
-
- def pull(self, rev):
- output, status = self.run('pull', self.path, all=True,
- match='hash %s' % rev,
- no_test=True, no_posthook=True,
- external_merge='/bin/false',
- repodir=self.tmppath)
- if status:
- if output.find('We have conflicts in') == -1:
- self.checkexit(status, output)
- output, status = self.run('revert', all=True, repodir=self.tmppath)
- self.checkexit(status, output)
-
- def getchanges(self, rev):
- copies = {}
- changes = []
- man = None
- for elt in self.changes[rev].find('summary').getchildren():
- if elt.tag in ('add_directory', 'remove_directory'):
- continue
- if elt.tag == 'move':
- if man is None:
- man = self.manifest()
- source, dest = elt.get('from'), elt.get('to')
- if source in man:
- # File move
- changes.append((source, rev))
- changes.append((dest, rev))
- copies[dest] = source
- else:
- # Directory move, deduce file moves from manifest
- source = source + '/'
- for f in man:
- if not f.startswith(source):
- continue
- fdest = dest + '/' + f[len(source):]
- changes.append((f, rev))
- changes.append((fdest, rev))
- copies[fdest] = f
- else:
- changes.append((elt.text.strip(), rev))
- self.pull(rev)
- self.lastrev = rev
- return sorted(changes), copies
-
- def getfile(self, name, rev):
- if rev != self.lastrev:
- raise util.Abort(_('internal calling inconsistency'))
- path = os.path.join(self.tmppath, name)
- data = open(path, 'rb').read()
- mode = os.lstat(path).st_mode
- mode = (mode & 0111) and 'x' or ''
- return data, mode
-
- def gettags(self):
- return self.tags
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.pyo
deleted file mode 100644
index 78b7568..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/darcs.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.py
deleted file mode 100644
index 1064642..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.py
+++ /dev/null
@@ -1,365 +0,0 @@
-# Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
-# Copyright 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import shlex
-from mercurial.i18n import _
-from mercurial import util
-from common import SKIPREV, converter_source
-
-def rpairs(name):
- e = len(name)
- while e != -1:
- yield name[:e], name[e + 1:]
- e = name.rfind('/', 0, e)
- yield '.', name
-
-class filemapper(object):
- '''Map and filter filenames when importing.
- A name can be mapped to itself, a new name, or None (omit from new
- repository).'''
-
- def __init__(self, ui, path=None):
- self.ui = ui
- self.include = {}
- self.exclude = {}
- self.rename = {}
- if path:
- if self.parse(path):
- raise util.Abort(_('errors in filemap'))
-
- def parse(self, path):
- errs = 0
- def check(name, mapping, listname):
- if not name:
- self.ui.warn(_('%s:%d: path to %s is missing\n') %
- (lex.infile, lex.lineno, listname))
- return 1
- if name in mapping:
- self.ui.warn(_('%s:%d: %r already in %s list\n') %
- (lex.infile, lex.lineno, name, listname))
- return 1
- if (name.startswith('/') or
- name.endswith('/') or
- '//' in name):
- self.ui.warn(_('%s:%d: superfluous / in %s %r\n') %
- (lex.infile, lex.lineno, listname, name))
- return 1
- return 0
- lex = shlex.shlex(open(path), path, True)
- lex.wordchars += '!@#$%^&*()-=+[]{}|;:,./<>?'
- cmd = lex.get_token()
- while cmd:
- if cmd == 'include':
- name = lex.get_token()
- errs += check(name, self.exclude, 'exclude')
- self.include[name] = name
- elif cmd == 'exclude':
- name = lex.get_token()
- errs += check(name, self.include, 'include')
- errs += check(name, self.rename, 'rename')
- self.exclude[name] = name
- elif cmd == 'rename':
- src = lex.get_token()
- dest = lex.get_token()
- errs += check(src, self.exclude, 'exclude')
- self.rename[src] = dest
- elif cmd == 'source':
- errs += self.parse(lex.get_token())
- else:
- self.ui.warn(_('%s:%d: unknown directive %r\n') %
- (lex.infile, lex.lineno, cmd))
- errs += 1
- cmd = lex.get_token()
- return errs
-
- def lookup(self, name, mapping):
- for pre, suf in rpairs(name):
- try:
- return mapping[pre], pre, suf
- except KeyError:
- pass
- return '', name, ''
-
- def __call__(self, name):
- if self.include:
- inc = self.lookup(name, self.include)[0]
- else:
- inc = name
- if self.exclude:
- exc = self.lookup(name, self.exclude)[0]
- else:
- exc = ''
- if (not self.include and exc) or (len(inc) <= len(exc)):
- return None
- newpre, pre, suf = self.lookup(name, self.rename)
- if newpre:
- if newpre == '.':
- return suf
- if suf:
- return newpre + '/' + suf
- return newpre
- return name
-
- def active(self):
- return bool(self.include or self.exclude or self.rename)
-
-# This class does two additional things compared to a regular source:
-#
-# - Filter and rename files. This is mostly wrapped by the filemapper
-# class above. We hide the original filename in the revision that is
-# returned by getchanges to be able to find things later in getfile.
-#
-# - Return only revisions that matter for the files we're interested in.
-# This involves rewriting the parents of the original revision to
-# create a graph that is restricted to those revisions.
-#
-# This set of revisions includes not only revisions that directly
-# touch files we're interested in, but also merges that merge two
-# or more interesting revisions.
-
-class filemap_source(converter_source):
- def __init__(self, ui, baseconverter, filemap):
- super(filemap_source, self).__init__(ui)
- self.base = baseconverter
- self.filemapper = filemapper(ui, filemap)
- self.commits = {}
- # if a revision rev has parent p in the original revision graph, then
- # rev will have parent self.parentmap[p] in the restricted graph.
- self.parentmap = {}
- # self.wantedancestors[rev] is the set of all ancestors of rev that
- # are in the restricted graph.
- self.wantedancestors = {}
- self.convertedorder = None
- self._rebuilt = False
- self.origparents = {}
- self.children = {}
- self.seenchildren = {}
-
- def before(self):
- self.base.before()
-
- def after(self):
- self.base.after()
-
- def setrevmap(self, revmap):
- # rebuild our state to make things restartable
- #
- # To avoid calling getcommit for every revision that has already
- # been converted, we rebuild only the parentmap, delaying the
- # rebuild of wantedancestors until we need it (i.e. until a
- # merge).
- #
- # We assume the order argument lists the revisions in
- # topological order, so that we can infer which revisions were
- # wanted by previous runs.
- self._rebuilt = not revmap
- seen = {SKIPREV: SKIPREV}
- dummyset = set()
- converted = []
- for rev in revmap.order:
- mapped = revmap[rev]
- wanted = mapped not in seen
- if wanted:
- seen[mapped] = rev
- self.parentmap[rev] = rev
- else:
- self.parentmap[rev] = seen[mapped]
- self.wantedancestors[rev] = dummyset
- arg = seen[mapped]
- if arg == SKIPREV:
- arg = None
- converted.append((rev, wanted, arg))
- self.convertedorder = converted
- return self.base.setrevmap(revmap)
-
- def rebuild(self):
- if self._rebuilt:
- return True
- self._rebuilt = True
- self.parentmap.clear()
- self.wantedancestors.clear()
- self.seenchildren.clear()
- for rev, wanted, arg in self.convertedorder:
- if rev not in self.origparents:
- self.origparents[rev] = self.getcommit(rev).parents
- if arg is not None:
- self.children[arg] = self.children.get(arg, 0) + 1
-
- for rev, wanted, arg in self.convertedorder:
- parents = self.origparents[rev]
- if wanted:
- self.mark_wanted(rev, parents)
- else:
- self.mark_not_wanted(rev, arg)
- self._discard(arg, *parents)
-
- return True
-
- def getheads(self):
- return self.base.getheads()
-
- def getcommit(self, rev):
- # We want to save a reference to the commit objects to be able
- # to rewrite their parents later on.
- c = self.commits[rev] = self.base.getcommit(rev)
- for p in c.parents:
- self.children[p] = self.children.get(p, 0) + 1
- return c
-
- def _discard(self, *revs):
- for r in revs:
- if r is None:
- continue
- self.seenchildren[r] = self.seenchildren.get(r, 0) + 1
- if self.seenchildren[r] == self.children[r]:
- del self.wantedancestors[r]
- del self.parentmap[r]
- del self.seenchildren[r]
- if self._rebuilt:
- del self.children[r]
-
- def wanted(self, rev, i):
- # Return True if we're directly interested in rev.
- #
- # i is an index selecting one of the parents of rev (if rev
- # has no parents, i is None). getchangedfiles will give us
- # the list of files that are different in rev and in the parent
- # indicated by i. If we're interested in any of these files,
- # we're interested in rev.
- try:
- files = self.base.getchangedfiles(rev, i)
- except NotImplementedError:
- raise util.Abort(_("source repository doesn't support --filemap"))
- for f in files:
- if self.filemapper(f):
- return True
- return False
-
- def mark_not_wanted(self, rev, p):
- # Mark rev as not interesting and update data structures.
-
- if p is None:
- # A root revision. Use SKIPREV to indicate that it doesn't
- # map to any revision in the restricted graph. Put SKIPREV
- # in the set of wanted ancestors to simplify code elsewhere
- self.parentmap[rev] = SKIPREV
- self.wantedancestors[rev] = set((SKIPREV,))
- return
-
- # Reuse the data from our parent.
- self.parentmap[rev] = self.parentmap[p]
- self.wantedancestors[rev] = self.wantedancestors[p]
-
- def mark_wanted(self, rev, parents):
- # Mark rev ss wanted and update data structures.
-
- # rev will be in the restricted graph, so children of rev in
- # the original graph should still have rev as a parent in the
- # restricted graph.
- self.parentmap[rev] = rev
-
- # The set of wanted ancestors of rev is the union of the sets
- # of wanted ancestors of its parents. Plus rev itself.
- wrev = set()
- for p in parents:
- wrev.update(self.wantedancestors[p])
- wrev.add(rev)
- self.wantedancestors[rev] = wrev
-
- def getchanges(self, rev):
- parents = self.commits[rev].parents
- if len(parents) > 1:
- self.rebuild()
-
- # To decide whether we're interested in rev we:
- #
- # - calculate what parents rev will have if it turns out we're
- # interested in it. If it's going to have more than 1 parent,
- # we're interested in it.
- #
- # - otherwise, we'll compare it with the single parent we found.
- # If any of the files we're interested in is different in the
- # the two revisions, we're interested in rev.
-
- # A parent p is interesting if its mapped version (self.parentmap[p]):
- # - is not SKIPREV
- # - is still not in the list of parents (we don't want duplicates)
- # - is not an ancestor of the mapped versions of the other parents
- mparents = []
- wp = None
- for i, p1 in enumerate(parents):
- mp1 = self.parentmap[p1]
- if mp1 == SKIPREV or mp1 in mparents:
- continue
- for p2 in parents:
- if p1 == p2 or mp1 == self.parentmap[p2]:
- continue
- if mp1 in self.wantedancestors[p2]:
- break
- else:
- mparents.append(mp1)
- wp = i
-
- if wp is None and parents:
- wp = 0
-
- self.origparents[rev] = parents
-
- closed = 'close' in self.commits[rev].extra
-
- if len(mparents) < 2 and not closed and not self.wanted(rev, wp):
- # We don't want this revision.
- # Update our state and tell the convert process to map this
- # revision to the same revision its parent as mapped to.
- p = None
- if parents:
- p = parents[wp]
- self.mark_not_wanted(rev, p)
- self.convertedorder.append((rev, False, p))
- self._discard(*parents)
- return self.parentmap[rev]
-
- # We want this revision.
- # Rewrite the parents of the commit object
- self.commits[rev].parents = mparents
- self.mark_wanted(rev, parents)
- self.convertedorder.append((rev, True, None))
- self._discard(*parents)
-
- # Get the real changes and do the filtering/mapping. To be
- # able to get the files later on in getfile, we hide the
- # original filename in the rev part of the return value.
- changes, copies = self.base.getchanges(rev)
- newnames = {}
- files = []
- for f, r in changes:
- newf = self.filemapper(f)
- if newf:
- files.append((newf, (f, r)))
- newnames[f] = newf
-
- ncopies = {}
- for c in copies:
- newc = self.filemapper(c)
- if newc:
- newsource = self.filemapper(copies[c])
- if newsource:
- ncopies[newc] = newsource
-
- return files, ncopies
-
- def getfile(self, name, rev):
- realname, realrev = rev
- return self.base.getfile(realname, realrev)
-
- def gettags(self):
- return self.base.gettags()
-
- def hasnativeorder(self):
- return self.base.hasnativeorder()
-
- def lookuprev(self, rev):
- return self.base.lookuprev(rev)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.pyo
deleted file mode 100644
index 2ece523..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/filemap.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.py
deleted file mode 100644
index e973031..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# git.py - git support for the convert extension
-#
-# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import os
-from mercurial import util
-from mercurial.node import hex, nullid
-from mercurial.i18n import _
-
-from common import NoRepo, commit, converter_source, checktool
-
-class convert_git(converter_source):
- # Windows does not support GIT_DIR= construct while other systems
- # cannot remove environment variable. Just assume none have
- # both issues.
- if hasattr(os, 'unsetenv'):
- def gitopen(self, s):
- prevgitdir = os.environ.get('GIT_DIR')
- os.environ['GIT_DIR'] = self.path
- try:
- return util.popen(s, 'rb')
- finally:
- if prevgitdir is None:
- del os.environ['GIT_DIR']
- else:
- os.environ['GIT_DIR'] = prevgitdir
- else:
- def gitopen(self, s):
- return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
-
- def gitread(self, s):
- fh = self.gitopen(s)
- data = fh.read()
- return data, fh.close()
-
- def __init__(self, ui, path, rev=None):
- super(convert_git, self).__init__(ui, path, rev=rev)
-
- if os.path.isdir(path + "/.git"):
- path += "/.git"
- if not os.path.exists(path + "/objects"):
- raise NoRepo(_("%s does not look like a Git repository") % path)
-
- checktool('git', 'git')
-
- self.path = path
-
- def getheads(self):
- if not self.rev:
- heads, ret = self.gitread('git rev-parse --branches --remotes')
- heads = heads.splitlines()
- else:
- heads, ret = self.gitread("git rev-parse --verify %s" % self.rev)
- heads = [heads[:-1]]
- if ret:
- raise util.Abort(_('cannot retrieve git heads'))
- return heads
-
- def catfile(self, rev, type):
- if rev == hex(nullid):
- raise IOError()
- data, ret = self.gitread("git cat-file %s %s" % (type, rev))
- if ret:
- raise util.Abort(_('cannot read %r object at %s') % (type, rev))
- return data
-
- def getfile(self, name, rev):
- data = self.catfile(rev, "blob")
- mode = self.modecache[(name, rev)]
- return data, mode
-
- def getchanges(self, version):
- self.modecache = {}
- fh = self.gitopen("git diff-tree -z --root -m -r %s" % version)
- changes = []
- seen = set()
- entry = None
- for l in fh.read().split('\x00'):
- if not entry:
- if not l.startswith(':'):
- continue
- entry = l
- continue
- f = l
- if f not in seen:
- seen.add(f)
- entry = entry.split()
- h = entry[3]
- p = (entry[1] == "100755")
- s = (entry[1] == "120000")
- self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
- changes.append((f, h))
- entry = None
- if fh.close():
- raise util.Abort(_('cannot read changes in %s') % version)
- return (changes, {})
-
- def getcommit(self, version):
- c = self.catfile(version, "commit") # read the commit hash
- end = c.find("\n\n")
- message = c[end + 2:]
- message = self.recode(message)
- l = c[:end].splitlines()
- parents = []
- author = committer = None
- for e in l[1:]:
- n, v = e.split(" ", 1)
- if n == "author":
- p = v.split()
- tm, tz = p[-2:]
- author = " ".join(p[:-2])
- if author[0] == "<": author = author[1:-1]
- author = self.recode(author)
- if n == "committer":
- p = v.split()
- tm, tz = p[-2:]
- committer = " ".join(p[:-2])
- if committer[0] == "<": committer = committer[1:-1]
- committer = self.recode(committer)
- if n == "parent":
- parents.append(v)
-
- if committer and committer != author:
- message += "\ncommitter: %s\n" % committer
- tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
- tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
- date = tm + " " + str(tz)
-
- c = commit(parents=parents, date=date, author=author, desc=message,
- rev=version)
- return c
-
- def gettags(self):
- tags = {}
- fh = self.gitopen('git ls-remote --tags "%s"' % self.path)
- prefix = 'refs/tags/'
- for line in fh:
- line = line.strip()
- if not line.endswith("^{}"):
- continue
- node, tag = line.split(None, 1)
- if not tag.startswith(prefix):
- continue
- tag = tag[len(prefix):-3]
- tags[tag] = node
- if fh.close():
- raise util.Abort(_('cannot read tags from %s') % self.path)
-
- return tags
-
- def getchangedfiles(self, version, i):
- changes = []
- if i is None:
- fh = self.gitopen("git diff-tree --root -m -r %s" % version)
- for l in fh:
- if "\t" not in l:
- continue
- m, f = l[:-1].split("\t")
- changes.append(f)
- else:
- fh = self.gitopen('git diff-tree --name-only --root -r %s "%s^%s" --'
- % (version, version, i + 1))
- changes = [f.rstrip('\n') for f in fh]
- if fh.close():
- raise util.Abort(_('cannot read changes in %s') % version)
-
- return changes
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.pyo
deleted file mode 100644
index 3166318..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/git.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.py
deleted file mode 100644
index 60cfede..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.py
+++ /dev/null
@@ -1,338 +0,0 @@
-# gnuarch.py - GNU Arch support for the convert extension
-#
-# Copyright 2008, 2009 Aleix Conchillo Flaque <aleix@member.fsf.org>
-# and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from common import NoRepo, commandline, commit, converter_source
-from mercurial.i18n import _
-from mercurial import encoding, util
-import os, shutil, tempfile, stat
-from email.Parser import Parser
-
-class gnuarch_source(converter_source, commandline):
-
- class gnuarch_rev(object):
- def __init__(self, rev):
- self.rev = rev
- self.summary = ''
- self.date = None
- self.author = ''
- self.continuationof = None
- self.add_files = []
- self.mod_files = []
- self.del_files = []
- self.ren_files = {}
- self.ren_dirs = {}
-
- def __init__(self, ui, path, rev=None):
- super(gnuarch_source, self).__init__(ui, path, rev=rev)
-
- if not os.path.exists(os.path.join(path, '{arch}')):
- raise NoRepo(_("%s does not look like a GNU Arch repository")
- % path)
-
- # Could use checktool, but we want to check for baz or tla.
- self.execmd = None
- if util.find_exe('baz'):
- self.execmd = 'baz'
- else:
- if util.find_exe('tla'):
- self.execmd = 'tla'
- else:
- raise util.Abort(_('cannot find a GNU Arch tool'))
-
- commandline.__init__(self, ui, self.execmd)
-
- self.path = os.path.realpath(path)
- self.tmppath = None
-
- self.treeversion = None
- self.lastrev = None
- self.changes = {}
- self.parents = {}
- self.tags = {}
- self.catlogparser = Parser()
- self.encoding = encoding.encoding
- self.archives = []
-
- def before(self):
- # Get registered archives
- self.archives = [i.rstrip('\n')
- for i in self.runlines0('archives', '-n')]
-
- if self.execmd == 'tla':
- output = self.run0('tree-version', self.path)
- else:
- output = self.run0('tree-version', '-d', self.path)
- self.treeversion = output.strip()
-
- # Get name of temporary directory
- version = self.treeversion.split('/')
- self.tmppath = os.path.join(tempfile.gettempdir(),
- 'hg-%s' % version[1])
-
- # Generate parents dictionary
- self.parents[None] = []
- treeversion = self.treeversion
- child = None
- while treeversion:
- self.ui.status(_('analyzing tree version %s...\n') % treeversion)
-
- archive = treeversion.split('/')[0]
- if archive not in self.archives:
- self.ui.status(_('tree analysis stopped because it points to '
- 'an unregistered archive %s...\n') % archive)
- break
-
- # Get the complete list of revisions for that tree version
- output, status = self.runlines('revisions', '-r', '-f', treeversion)
- self.checkexit(status, 'failed retrieveing revisions for %s'
- % treeversion)
-
- # No new iteration unless a revision has a continuation-of header
- treeversion = None
-
- for l in output:
- rev = l.strip()
- self.changes[rev] = self.gnuarch_rev(rev)
- self.parents[rev] = []
-
- # Read author, date and summary
- catlog, status = self.run('cat-log', '-d', self.path, rev)
- if status:
- catlog = self.run0('cat-archive-log', rev)
- self._parsecatlog(catlog, rev)
-
- # Populate the parents map
- self.parents[child].append(rev)
-
- # Keep track of the current revision as the child of the next
- # revision scanned
- child = rev
-
- # Check if we have to follow the usual incremental history
- # or if we have to 'jump' to a different treeversion given
- # by the continuation-of header.
- if self.changes[rev].continuationof:
- treeversion = '--'.join(
- self.changes[rev].continuationof.split('--')[:-1])
- break
-
- # If we reached a base-0 revision w/o any continuation-of
- # header, it means the tree history ends here.
- if rev[-6:] == 'base-0':
- break
-
- def after(self):
- self.ui.debug('cleaning up %s\n' % self.tmppath)
- shutil.rmtree(self.tmppath, ignore_errors=True)
-
- def getheads(self):
- return self.parents[None]
-
- def getfile(self, name, rev):
- if rev != self.lastrev:
- raise util.Abort(_('internal calling inconsistency'))
-
- # Raise IOError if necessary (i.e. deleted files).
- if not os.path.lexists(os.path.join(self.tmppath, name)):
- raise IOError
-
- return self._getfile(name, rev)
-
- def getchanges(self, rev):
- self._update(rev)
- changes = []
- copies = {}
-
- for f in self.changes[rev].add_files:
- changes.append((f, rev))
-
- for f in self.changes[rev].mod_files:
- changes.append((f, rev))
-
- for f in self.changes[rev].del_files:
- changes.append((f, rev))
-
- for src in self.changes[rev].ren_files:
- to = self.changes[rev].ren_files[src]
- changes.append((src, rev))
- changes.append((to, rev))
- copies[to] = src
-
- for src in self.changes[rev].ren_dirs:
- to = self.changes[rev].ren_dirs[src]
- chgs, cps = self._rendirchanges(src, to)
- changes += [(f, rev) for f in chgs]
- copies.update(cps)
-
- self.lastrev = rev
- return sorted(set(changes)), copies
-
- def getcommit(self, rev):
- changes = self.changes[rev]
- return commit(author=changes.author, date=changes.date,
- desc=changes.summary, parents=self.parents[rev], rev=rev)
-
- def gettags(self):
- return self.tags
-
- def _execute(self, cmd, *args, **kwargs):
- cmdline = [self.execmd, cmd]
- cmdline += args
- cmdline = [util.shellquote(arg) for arg in cmdline]
- cmdline += ['>', util.nulldev, '2>', util.nulldev]
- cmdline = util.quotecommand(' '.join(cmdline))
- self.ui.debug(cmdline, '\n')
- return os.system(cmdline)
-
- def _update(self, rev):
- self.ui.debug('applying revision %s...\n' % rev)
- changeset, status = self.runlines('replay', '-d', self.tmppath,
- rev)
- if status:
- # Something went wrong while merging (baz or tla
- # issue?), get latest revision and try from there
- shutil.rmtree(self.tmppath, ignore_errors=True)
- self._obtainrevision(rev)
- else:
- old_rev = self.parents[rev][0]
- self.ui.debug('computing changeset between %s and %s...\n'
- % (old_rev, rev))
- self._parsechangeset(changeset, rev)
-
- def _getfile(self, name, rev):
- mode = os.lstat(os.path.join(self.tmppath, name)).st_mode
- if stat.S_ISLNK(mode):
- data = os.readlink(os.path.join(self.tmppath, name))
- mode = mode and 'l' or ''
- else:
- data = open(os.path.join(self.tmppath, name), 'rb').read()
- mode = (mode & 0111) and 'x' or ''
- return data, mode
-
- def _exclude(self, name):
- exclude = ['{arch}', '.arch-ids', '.arch-inventory']
- for exc in exclude:
- if name.find(exc) != -1:
- return True
- return False
-
- def _readcontents(self, path):
- files = []
- contents = os.listdir(path)
- while len(contents) > 0:
- c = contents.pop()
- p = os.path.join(path, c)
- # os.walk could be used, but here we avoid internal GNU
- # Arch files and directories, thus saving a lot time.
- if not self._exclude(p):
- if os.path.isdir(p):
- contents += [os.path.join(c, f) for f in os.listdir(p)]
- else:
- files.append(c)
- return files
-
- def _rendirchanges(self, src, dest):
- changes = []
- copies = {}
- files = self._readcontents(os.path.join(self.tmppath, dest))
- for f in files:
- s = os.path.join(src, f)
- d = os.path.join(dest, f)
- changes.append(s)
- changes.append(d)
- copies[d] = s
- return changes, copies
-
- def _obtainrevision(self, rev):
- self.ui.debug('obtaining revision %s...\n' % rev)
- output = self._execute('get', rev, self.tmppath)
- self.checkexit(output)
- self.ui.debug('analyzing revision %s...\n' % rev)
- files = self._readcontents(self.tmppath)
- self.changes[rev].add_files += files
-
- def _stripbasepath(self, path):
- if path.startswith('./'):
- return path[2:]
- return path
-
- def _parsecatlog(self, data, rev):
- try:
- catlog = self.catlogparser.parsestr(data)
-
- # Commit date
- self.changes[rev].date = util.datestr(
- util.strdate(catlog['Standard-date'],
- '%Y-%m-%d %H:%M:%S'))
-
- # Commit author
- self.changes[rev].author = self.recode(catlog['Creator'])
-
- # Commit description
- self.changes[rev].summary = '\n\n'.join((catlog['Summary'],
- catlog.get_payload()))
- self.changes[rev].summary = self.recode(self.changes[rev].summary)
-
- # Commit revision origin when dealing with a branch or tag
- if 'Continuation-of' in catlog:
- self.changes[rev].continuationof = self.recode(
- catlog['Continuation-of'])
- except Exception:
- raise util.Abort(_('could not parse cat-log of %s') % rev)
-
- def _parsechangeset(self, data, rev):
- for l in data:
- l = l.strip()
- # Added file (ignore added directory)
- if l.startswith('A') and not l.startswith('A/'):
- file = self._stripbasepath(l[1:].strip())
- if not self._exclude(file):
- self.changes[rev].add_files.append(file)
- # Deleted file (ignore deleted directory)
- elif l.startswith('D') and not l.startswith('D/'):
- file = self._stripbasepath(l[1:].strip())
- if not self._exclude(file):
- self.changes[rev].del_files.append(file)
- # Modified binary file
- elif l.startswith('Mb'):
- file = self._stripbasepath(l[2:].strip())
- if not self._exclude(file):
- self.changes[rev].mod_files.append(file)
- # Modified link
- elif l.startswith('M->'):
- file = self._stripbasepath(l[3:].strip())
- if not self._exclude(file):
- self.changes[rev].mod_files.append(file)
- # Modified file
- elif l.startswith('M'):
- file = self._stripbasepath(l[1:].strip())
- if not self._exclude(file):
- self.changes[rev].mod_files.append(file)
- # Renamed file (or link)
- elif l.startswith('=>'):
- files = l[2:].strip().split(' ')
- if len(files) == 1:
- files = l[2:].strip().split('\t')
- src = self._stripbasepath(files[0])
- dst = self._stripbasepath(files[1])
- if not self._exclude(src) and not self._exclude(dst):
- self.changes[rev].ren_files[src] = dst
- # Conversion from file to link or from link to file (modified)
- elif l.startswith('ch'):
- file = self._stripbasepath(l[2:].strip())
- if not self._exclude(file):
- self.changes[rev].mod_files.append(file)
- # Renamed directory
- elif l.startswith('/>'):
- dirs = l[2:].strip().split(' ')
- if len(dirs) == 1:
- dirs = l[2:].strip().split('\t')
- src = self._stripbasepath(dirs[0])
- dst = self._stripbasepath(dirs[1])
- if not self._exclude(src) and not self._exclude(dst):
- self.changes[rev].ren_dirs[src] = dst
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.pyo
deleted file mode 100644
index 0e564ba..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/gnuarch.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.py
deleted file mode 100644
index 183377d..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.py
+++ /dev/null
@@ -1,376 +0,0 @@
-# hg.py - hg backend for convert extension
-#
-# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-# Notes for hg->hg conversion:
-#
-# * Old versions of Mercurial didn't trim the whitespace from the ends
-# of commit messages, but new versions do. Changesets created by
-# those older versions, then converted, may thus have different
-# hashes for changesets that are otherwise identical.
-#
-# * Using "--config convert.hg.saverev=true" will make the source
-# identifier to be stored in the converted revision. This will cause
-# the converted revision to have a different identity than the
-# source.
-
-
-import os, time, cStringIO
-from mercurial.i18n import _
-from mercurial.node import bin, hex, nullid
-from mercurial import hg, util, context, error
-
-from common import NoRepo, commit, converter_source, converter_sink
-
-class mercurial_sink(converter_sink):
- def __init__(self, ui, path):
- converter_sink.__init__(self, ui, path)
- self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
- self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
- self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
- self.lastbranch = None
- if os.path.isdir(path) and len(os.listdir(path)) > 0:
- try:
- self.repo = hg.repository(self.ui, path)
- if not self.repo.local():
- raise NoRepo(_('%s is not a local Mercurial repository')
- % path)
- except error.RepoError, err:
- ui.traceback()
- raise NoRepo(err.args[0])
- else:
- try:
- ui.status(_('initializing destination %s repository\n') % path)
- self.repo = hg.repository(self.ui, path, create=True)
- if not self.repo.local():
- raise NoRepo(_('%s is not a local Mercurial repository')
- % path)
- self.created.append(path)
- except error.RepoError:
- ui.traceback()
- raise NoRepo(_("could not create hg repository %s as sink")
- % path)
- self.lock = None
- self.wlock = None
- self.filemapmode = False
-
- def before(self):
- self.ui.debug('run hg sink pre-conversion action\n')
- self.wlock = self.repo.wlock()
- self.lock = self.repo.lock()
-
- def after(self):
- self.ui.debug('run hg sink post-conversion action\n')
- if self.lock:
- self.lock.release()
- if self.wlock:
- self.wlock.release()
-
- def revmapfile(self):
- return os.path.join(self.path, ".hg", "shamap")
-
- def authorfile(self):
- return os.path.join(self.path, ".hg", "authormap")
-
- def getheads(self):
- h = self.repo.changelog.heads()
- return [hex(x) for x in h]
-
- def setbranch(self, branch, pbranches):
- if not self.clonebranches:
- return
-
- setbranch = (branch != self.lastbranch)
- self.lastbranch = branch
- if not branch:
- branch = 'default'
- pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
- pbranch = pbranches and pbranches[0][1] or 'default'
-
- branchpath = os.path.join(self.path, branch)
- if setbranch:
- self.after()
- try:
- self.repo = hg.repository(self.ui, branchpath)
- except:
- self.repo = hg.repository(self.ui, branchpath, create=True)
- self.before()
-
- # pbranches may bring revisions from other branches (merge parents)
- # Make sure we have them, or pull them.
- missings = {}
- for b in pbranches:
- try:
- self.repo.lookup(b[0])
- except:
- missings.setdefault(b[1], []).append(b[0])
-
- if missings:
- self.after()
- for pbranch, heads in missings.iteritems():
- pbranchpath = os.path.join(self.path, pbranch)
- prepo = hg.repository(self.ui, pbranchpath)
- self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
- self.repo.pull(prepo, [prepo.lookup(h) for h in heads])
- self.before()
-
- def _rewritetags(self, source, revmap, data):
- fp = cStringIO.StringIO()
- for line in data.splitlines():
- s = line.split(' ', 1)
- if len(s) != 2:
- continue
- revid = revmap.get(source.lookuprev(s[0]))
- if not revid:
- continue
- fp.write('%s %s\n' % (revid, s[1]))
- return fp.getvalue()
-
- def putcommit(self, files, copies, parents, commit, source, revmap):
-
- files = dict(files)
- def getfilectx(repo, memctx, f):
- v = files[f]
- data, mode = source.getfile(f, v)
- if f == '.hgtags':
- data = self._rewritetags(source, revmap, data)
- return context.memfilectx(f, data, 'l' in mode, 'x' in mode,
- copies.get(f))
-
- pl = []
- for p in parents:
- if p not in pl:
- pl.append(p)
- parents = pl
- nparents = len(parents)
- if self.filemapmode and nparents == 1:
- m1node = self.repo.changelog.read(bin(parents[0]))[0]
- parent = parents[0]
-
- if len(parents) < 2:
- parents.append(nullid)
- if len(parents) < 2:
- parents.append(nullid)
- p2 = parents.pop(0)
-
- text = commit.desc
- extra = commit.extra.copy()
- if self.branchnames and commit.branch:
- extra['branch'] = commit.branch
- if commit.rev:
- extra['convert_revision'] = commit.rev
-
- while parents:
- p1 = p2
- p2 = parents.pop(0)
- ctx = context.memctx(self.repo, (p1, p2), text, files.keys(),
- getfilectx, commit.author, commit.date, extra)
- self.repo.commitctx(ctx)
- text = "(octopus merge fixup)\n"
- p2 = hex(self.repo.changelog.tip())
-
- if self.filemapmode and nparents == 1:
- man = self.repo.manifest
- mnode = self.repo.changelog.read(bin(p2))[0]
- closed = 'close' in commit.extra
- if not closed and not man.cmp(m1node, man.revision(mnode)):
- self.ui.status(_("filtering out empty revision\n"))
- self.repo.rollback()
- return parent
- return p2
-
- def puttags(self, tags):
- try:
- parentctx = self.repo[self.tagsbranch]
- tagparent = parentctx.node()
- except error.RepoError:
- parentctx = None
- tagparent = nullid
-
- try:
- oldlines = sorted(parentctx['.hgtags'].data().splitlines(True))
- except:
- oldlines = []
-
- newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
- if newlines == oldlines:
- return None, None
- data = "".join(newlines)
- def getfilectx(repo, memctx, f):
- return context.memfilectx(f, data, False, False, None)
-
- self.ui.status(_("updating tags\n"))
- date = "%s 0" % int(time.mktime(time.gmtime()))
- extra = {'branch': self.tagsbranch}
- ctx = context.memctx(self.repo, (tagparent, None), "update tags",
- [".hgtags"], getfilectx, "convert-repo", date,
- extra)
- self.repo.commitctx(ctx)
- return hex(self.repo.changelog.tip()), hex(tagparent)
-
- def setfilemapmode(self, active):
- self.filemapmode = active
-
-class mercurial_source(converter_source):
- def __init__(self, ui, path, rev=None):
- converter_source.__init__(self, ui, path, rev)
- self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
- self.ignored = set()
- self.saverev = ui.configbool('convert', 'hg.saverev', False)
- try:
- self.repo = hg.repository(self.ui, path)
- # try to provoke an exception if this isn't really a hg
- # repo, but some other bogus compatible-looking url
- if not self.repo.local():
- raise error.RepoError()
- except error.RepoError:
- ui.traceback()
- raise NoRepo(_("%s is not a local Mercurial repository") % path)
- self.lastrev = None
- self.lastctx = None
- self._changescache = None
- self.convertfp = None
- # Restrict converted revisions to startrev descendants
- startnode = ui.config('convert', 'hg.startrev')
- if startnode is not None:
- try:
- startnode = self.repo.lookup(startnode)
- except error.RepoError:
- raise util.Abort(_('%s is not a valid start revision')
- % startnode)
- startrev = self.repo.changelog.rev(startnode)
- children = {startnode: 1}
- for rev in self.repo.changelog.descendants(startrev):
- children[self.repo.changelog.node(rev)] = 1
- self.keep = children.__contains__
- else:
- self.keep = util.always
-
- def changectx(self, rev):
- if self.lastrev != rev:
- self.lastctx = self.repo[rev]
- self.lastrev = rev
- return self.lastctx
-
- def parents(self, ctx):
- return [p for p in ctx.parents() if p and self.keep(p.node())]
-
- def getheads(self):
- if self.rev:
- heads = [self.repo[self.rev].node()]
- else:
- heads = self.repo.heads()
- return [hex(h) for h in heads if self.keep(h)]
-
- def getfile(self, name, rev):
- try:
- fctx = self.changectx(rev)[name]
- return fctx.data(), fctx.flags()
- except error.LookupError, err:
- raise IOError(err)
-
- def getchanges(self, rev):
- ctx = self.changectx(rev)
- parents = self.parents(ctx)
- if not parents:
- files = sorted(ctx.manifest())
- if self.ignoreerrors:
- # calling getcopies() is a simple way to detect missing
- # revlogs and populate self.ignored
- self.getcopies(ctx, parents, files)
- return [(f, rev) for f in files if f not in self.ignored], {}
- if self._changescache and self._changescache[0] == rev:
- m, a, r = self._changescache[1]
- else:
- m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
- # getcopies() detects missing revlogs early, run it before
- # filtering the changes.
- copies = self.getcopies(ctx, parents, m + a)
- changes = [(name, rev) for name in m + a + r
- if name not in self.ignored]
- return sorted(changes), copies
-
- def getcopies(self, ctx, parents, files):
- copies = {}
- for name in files:
- if name in self.ignored:
- continue
- try:
- copysource, copynode = ctx.filectx(name).renamed()
- if copysource in self.ignored or not self.keep(copynode):
- continue
- # Ignore copy sources not in parent revisions
- found = False
- for p in parents:
- if copysource in p:
- found = True
- break
- if not found:
- continue
- copies[name] = copysource
- except TypeError:
- pass
- except error.LookupError, e:
- if not self.ignoreerrors:
- raise
- self.ignored.add(name)
- self.ui.warn(_('ignoring: %s\n') % e)
- return copies
-
- def getcommit(self, rev):
- ctx = self.changectx(rev)
- parents = [p.hex() for p in self.parents(ctx)]
- if self.saverev:
- crev = rev
- else:
- crev = None
- return commit(author=ctx.user(), date=util.datestr(ctx.date()),
- desc=ctx.description(), rev=crev, parents=parents,
- branch=ctx.branch(), extra=ctx.extra(),
- sortkey=ctx.rev())
-
- def gettags(self):
- tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
- return dict([(name, hex(node)) for name, node in tags
- if self.keep(node)])
-
- def getchangedfiles(self, rev, i):
- ctx = self.changectx(rev)
- parents = self.parents(ctx)
- if not parents and i is None:
- i = 0
- changes = [], ctx.manifest().keys(), []
- else:
- i = i or 0
- changes = self.repo.status(parents[i].node(), ctx.node())[:3]
- changes = [[f for f in l if f not in self.ignored] for l in changes]
-
- if i == 0:
- self._changescache = (rev, changes)
-
- return changes[0] + changes[1] + changes[2]
-
- def converted(self, rev, destrev):
- if self.convertfp is None:
- self.convertfp = open(os.path.join(self.path, '.hg', 'shamap'),
- 'a')
- self.convertfp.write('%s %s\n' % (destrev, rev))
- self.convertfp.flush()
-
- def before(self):
- self.ui.debug('run hg source pre-conversion action\n')
-
- def after(self):
- self.ui.debug('run hg source post-conversion action\n')
-
- def hasnativeorder(self):
- return True
-
- def lookuprev(self, rev):
- try:
- return hex(self.repo.lookup(rev))
- except error.RepoError:
- return None
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.pyo
deleted file mode 100644
index 633af5e..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/hg.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.py
deleted file mode 100644
index 151ddc5..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# monotone.py - monotone support for the convert extension
-#
-# Copyright 2008, 2009 Mikkel Fahnoe Jorgensen <mikkel@dvide.com> and
-# others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import os, re
-from mercurial import util
-from common import NoRepo, commit, converter_source, checktool
-from common import commandline
-from mercurial.i18n import _
-
-class monotone_source(converter_source, commandline):
- def __init__(self, ui, path=None, rev=None):
- converter_source.__init__(self, ui, path, rev)
- commandline.__init__(self, ui, 'mtn')
-
- self.ui = ui
- self.path = path
-
- norepo = NoRepo(_("%s does not look like a monotone repository")
- % path)
- if not os.path.exists(os.path.join(path, '_MTN')):
- # Could be a monotone repository (SQLite db file)
- try:
- header = file(path, 'rb').read(16)
- except:
- header = ''
- if header != 'SQLite format 3\x00':
- raise norepo
-
- # regular expressions for parsing monotone output
- space = r'\s*'
- name = r'\s+"((?:\\"|[^"])*)"\s*'
- value = name
- revision = r'\s+\[(\w+)\]\s*'
- lines = r'(?:.|\n)+'
-
- self.dir_re = re.compile(space + "dir" + name)
- self.file_re = re.compile(space + "file" + name +
- "content" + revision)
- self.add_file_re = re.compile(space + "add_file" + name +
- "content" + revision)
- self.patch_re = re.compile(space + "patch" + name +
- "from" + revision + "to" + revision)
- self.rename_re = re.compile(space + "rename" + name + "to" + name)
- self.delete_re = re.compile(space + "delete" + name)
- self.tag_re = re.compile(space + "tag" + name + "revision" +
- revision)
- self.cert_re = re.compile(lines + space + "name" + name +
- "value" + value)
-
- attr = space + "file" + lines + space + "attr" + space
- self.attr_execute_re = re.compile(attr + '"mtn:execute"' +
- space + '"true"')
-
- # cached data
- self.manifest_rev = None
- self.manifest = None
- self.files = None
- self.dirs = None
-
- checktool('mtn', abort=False)
-
- # test if there are any revisions
- self.rev = None
- try:
- self.getheads()
- except:
- raise norepo
- self.rev = rev
-
- def mtnrun(self, *args, **kwargs):
- kwargs['d'] = self.path
- return self.run0('automate', *args, **kwargs)
-
- def mtnloadmanifest(self, rev):
- if self.manifest_rev == rev:
- return
- self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
- self.manifest_rev = rev
- self.files = {}
- self.dirs = {}
-
- for e in self.manifest:
- m = self.file_re.match(e)
- if m:
- attr = ""
- name = m.group(1)
- node = m.group(2)
- if self.attr_execute_re.match(e):
- attr += "x"
- self.files[name] = (node, attr)
- m = self.dir_re.match(e)
- if m:
- self.dirs[m.group(1)] = True
-
- def mtnisfile(self, name, rev):
- # a non-file could be a directory or a deleted or renamed file
- self.mtnloadmanifest(rev)
- return name in self.files
-
- def mtnisdir(self, name, rev):
- self.mtnloadmanifest(rev)
- return name in self.dirs
-
- def mtngetcerts(self, rev):
- certs = {"author":"<missing>", "date":"<missing>",
- "changelog":"<missing>", "branch":"<missing>"}
- certlist = self.mtnrun("certs", rev)
- # mtn < 0.45:
- # key "test@selenic.com"
- # mtn >= 0.45:
- # key [ff58a7ffb771907c4ff68995eada1c4da068d328]
- certlist = re.split('\n\n key ["\[]', certlist)
- for e in certlist:
- m = self.cert_re.match(e)
- if m:
- name, value = m.groups()
- value = value.replace(r'\"', '"')
- value = value.replace(r'\\', '\\')
- certs[name] = value
- # Monotone may have subsecond dates: 2005-02-05T09:39:12.364306
- # and all times are stored in UTC
- certs["date"] = certs["date"].split('.')[0] + " UTC"
- return certs
-
- # implement the converter_source interface:
-
- def getheads(self):
- if not self.rev:
- return self.mtnrun("leaves").splitlines()
- else:
- return [self.rev]
-
- def getchanges(self, rev):
- #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
- revision = self.mtnrun("get_revision", rev).split("\n\n")
- files = {}
- ignoremove = {}
- renameddirs = []
- copies = {}
- for e in revision:
- m = self.add_file_re.match(e)
- if m:
- files[m.group(1)] = rev
- ignoremove[m.group(1)] = rev
- m = self.patch_re.match(e)
- if m:
- files[m.group(1)] = rev
- # Delete/rename is handled later when the convert engine
- # discovers an IOError exception from getfile,
- # but only if we add the "from" file to the list of changes.
- m = self.delete_re.match(e)
- if m:
- files[m.group(1)] = rev
- m = self.rename_re.match(e)
- if m:
- toname = m.group(2)
- fromname = m.group(1)
- if self.mtnisfile(toname, rev):
- ignoremove[toname] = 1
- copies[toname] = fromname
- files[toname] = rev
- files[fromname] = rev
- elif self.mtnisdir(toname, rev):
- renameddirs.append((fromname, toname))
-
- # Directory renames can be handled only once we have recorded
- # all new files
- for fromdir, todir in renameddirs:
- renamed = {}
- for tofile in self.files:
- if tofile in ignoremove:
- continue
- if tofile.startswith(todir + '/'):
- renamed[tofile] = fromdir + tofile[len(todir):]
- # Avoid chained moves like:
- # d1(/a) => d3/d1(/a)
- # d2 => d3
- ignoremove[tofile] = 1
- for tofile, fromfile in renamed.items():
- self.ui.debug (_("copying file in renamed directory "
- "from '%s' to '%s'")
- % (fromfile, tofile), '\n')
- files[tofile] = rev
- copies[tofile] = fromfile
- for fromfile in renamed.values():
- files[fromfile] = rev
-
- return (files.items(), copies)
-
- def getfile(self, name, rev):
- if not self.mtnisfile(name, rev):
- raise IOError() # file was deleted or renamed
- try:
- data = self.mtnrun("get_file_of", name, r=rev)
- except:
- raise IOError() # file was deleted or renamed
- self.mtnloadmanifest(rev)
- node, attr = self.files.get(name, (None, ""))
- return data, attr
-
- def getcommit(self, rev):
- certs = self.mtngetcerts(rev)
- return commit(
- author=certs["author"],
- date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
- desc=certs["changelog"],
- rev=rev,
- parents=self.mtnrun("parents", rev).splitlines(),
- branch=certs["branch"])
-
- def gettags(self):
- tags = {}
- for e in self.mtnrun("tags").split("\n\n"):
- m = self.tag_re.match(e)
- if m:
- tags[m.group(1)] = m.group(2)
- return tags
-
- def getchangedfiles(self, rev, i):
- # This function is only needed to support --filemap
- # ... and we don't support that
- raise NotImplementedError()
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.pyo
deleted file mode 100644
index b51d266..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/monotone.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.py
deleted file mode 100644
index 5d640ad..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# Perforce source for convert extension.
-#
-# Copyright 2009, Frank Kingswood <frank@kingswood-consulting.co.uk>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-from mercurial import util
-from mercurial.i18n import _
-
-from common import commit, converter_source, checktool, NoRepo
-import marshal
-import re
-
-def loaditer(f):
- "Yield the dictionary objects generated by p4"
- try:
- while True:
- d = marshal.load(f)
- if not d:
- break
- yield d
- except EOFError:
- pass
-
-class p4_source(converter_source):
- def __init__(self, ui, path, rev=None):
- super(p4_source, self).__init__(ui, path, rev=rev)
-
- if "/" in path and not path.startswith('//'):
- raise NoRepo(_('%s does not look like a P4 repository') % path)
-
- checktool('p4', abort=False)
-
- self.p4changes = {}
- self.heads = {}
- self.changeset = {}
- self.files = {}
- self.tags = {}
- self.lastbranch = {}
- self.parent = {}
- self.encoding = "latin_1"
- self.depotname = {} # mapping from local name to depot name
- self.re_type = re.compile(
- "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)"
- "(\+\w+)?$")
- self.re_keywords = re.compile(
- r"\$(Id|Header|Date|DateTime|Change|File|Revision|Author)"
- r":[^$\n]*\$")
- self.re_keywords_old = re.compile("\$(Id|Header):[^$\n]*\$")
-
- self._parse(ui, path)
-
- def _parse_view(self, path):
- "Read changes affecting the path"
- cmd = 'p4 -G changes -s submitted %s' % util.shellquote(path)
- stdout = util.popen(cmd, mode='rb')
- for d in loaditer(stdout):
- c = d.get("change", None)
- if c:
- self.p4changes[c] = True
-
- def _parse(self, ui, path):
- "Prepare list of P4 filenames and revisions to import"
- ui.status(_('reading p4 views\n'))
-
- # read client spec or view
- if "/" in path:
- self._parse_view(path)
- if path.startswith("//") and path.endswith("/..."):
- views = {path[:-3]:""}
- else:
- views = {"//": ""}
- else:
- cmd = 'p4 -G client -o %s' % util.shellquote(path)
- clientspec = marshal.load(util.popen(cmd, mode='rb'))
-
- views = {}
- for client in clientspec:
- if client.startswith("View"):
- sview, cview = clientspec[client].split()
- self._parse_view(sview)
- if sview.endswith("...") and cview.endswith("..."):
- sview = sview[:-3]
- cview = cview[:-3]
- cview = cview[2:]
- cview = cview[cview.find("/") + 1:]
- views[sview] = cview
-
- # list of changes that affect our source files
- self.p4changes = self.p4changes.keys()
- self.p4changes.sort(key=int)
-
- # list with depot pathnames, longest first
- vieworder = views.keys()
- vieworder.sort(key=len, reverse=True)
-
- # handle revision limiting
- startrev = self.ui.config('convert', 'p4.startrev', default=0)
- self.p4changes = [x for x in self.p4changes
- if ((not startrev or int(x) >= int(startrev)) and
- (not self.rev or int(x) <= int(self.rev)))]
-
- # now read the full changelists to get the list of file revisions
- ui.status(_('collecting p4 changelists\n'))
- lastid = None
- for change in self.p4changes:
- cmd = "p4 -G describe -s %s" % change
- stdout = util.popen(cmd, mode='rb')
- d = marshal.load(stdout)
- desc = self.recode(d["desc"])
- shortdesc = desc.split("\n", 1)[0]
- t = '%s %s' % (d["change"], repr(shortdesc)[1:-1])
- ui.status(util.ellipsis(t, 80) + '\n')
-
- if lastid:
- parents = [lastid]
- else:
- parents = []
-
- date = (int(d["time"]), 0) # timezone not set
- c = commit(author=self.recode(d["user"]), date=util.datestr(date),
- parents=parents, desc=desc, branch='',
- extra={"p4": change})
-
- files = []
- i = 0
- while ("depotFile%d" % i) in d and ("rev%d" % i) in d:
- oldname = d["depotFile%d" % i]
- filename = None
- for v in vieworder:
- if oldname.startswith(v):
- filename = views[v] + oldname[len(v):]
- break
- if filename:
- files.append((filename, d["rev%d" % i]))
- self.depotname[filename] = oldname
- i += 1
- self.changeset[change] = c
- self.files[change] = files
- lastid = change
-
- if lastid:
- self.heads = [lastid]
-
- def getheads(self):
- return self.heads
-
- def getfile(self, name, rev):
- cmd = 'p4 -G print %s' \
- % util.shellquote("%s#%s" % (self.depotname[name], rev))
- stdout = util.popen(cmd, mode='rb')
-
- mode = None
- contents = ""
- keywords = None
-
- for d in loaditer(stdout):
- code = d["code"]
- data = d.get("data")
-
- if code == "error":
- raise IOError(d["generic"], data)
-
- elif code == "stat":
- p4type = self.re_type.match(d["type"])
- if p4type:
- mode = ""
- flags = (p4type.group(1) or "") + (p4type.group(3) or "")
- if "x" in flags:
- mode = "x"
- if p4type.group(2) == "symlink":
- mode = "l"
- if "ko" in flags:
- keywords = self.re_keywords_old
- elif "k" in flags:
- keywords = self.re_keywords
-
- elif code == "text" or code == "binary":
- contents += data
-
- if mode is None:
- raise IOError(0, "bad stat")
-
- if keywords:
- contents = keywords.sub("$\\1$", contents)
- if mode == "l" and contents.endswith("\n"):
- contents = contents[:-1]
-
- return contents, mode
-
- def getchanges(self, rev):
- return self.files[rev], {}
-
- def getcommit(self, rev):
- return self.changeset[rev]
-
- def gettags(self):
- return self.tags
-
- def getchangedfiles(self, rev, i):
- return sorted([x[0] for x in self.files[rev]])
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.pyo
deleted file mode 100644
index 45f1e2a..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/p4.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.py
deleted file mode 100644
index f2d26ad..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.py
+++ /dev/null
@@ -1,1168 +0,0 @@
-# Subversion 1.4/1.5 Python API backend
-#
-# Copyright(C) 2007 Daniel Holth et al
-
-import os
-import re
-import sys
-import cPickle as pickle
-import tempfile
-import urllib
-import urllib2
-
-from mercurial import strutil, util, encoding
-from mercurial.i18n import _
-
-# Subversion stuff. Works best with very recent Python SVN bindings
-# e.g. SVN 1.5 or backports. Thanks to the bzr folks for enhancing
-# these bindings.
-
-from cStringIO import StringIO
-
-from common import NoRepo, MissingTool, commit, encodeargs, decodeargs
-from common import commandline, converter_source, converter_sink, mapfile
-
-try:
- from svn.core import SubversionException, Pool
- import svn
- import svn.client
- import svn.core
- import svn.ra
- import svn.delta
- import transport
- import warnings
- warnings.filterwarnings('ignore',
- module='svn.core',
- category=DeprecationWarning)
-
-except ImportError:
- pass
-
-class SvnPathNotFound(Exception):
- pass
-
-def geturl(path):
- try:
- return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
- except SubversionException:
- pass
- if os.path.isdir(path):
- path = os.path.normpath(os.path.abspath(path))
- if os.name == 'nt':
- path = '/' + util.normpath(path)
- # Module URL is later compared with the repository URL returned
- # by svn API, which is UTF-8.
- path = encoding.tolocal(path)
- return 'file://%s' % urllib.quote(path)
- return path
-
-def optrev(number):
- optrev = svn.core.svn_opt_revision_t()
- optrev.kind = svn.core.svn_opt_revision_number
- optrev.value.number = number
- return optrev
-
-class changedpath(object):
- def __init__(self, p):
- self.copyfrom_path = p.copyfrom_path
- self.copyfrom_rev = p.copyfrom_rev
- self.action = p.action
-
-def get_log_child(fp, url, paths, start, end, limit=0, discover_changed_paths=True,
- strict_node_history=False):
- protocol = -1
- def receiver(orig_paths, revnum, author, date, message, pool):
- if orig_paths is not None:
- for k, v in orig_paths.iteritems():
- orig_paths[k] = changedpath(v)
- pickle.dump((orig_paths, revnum, author, date, message),
- fp, protocol)
-
- try:
- # Use an ra of our own so that our parent can consume
- # our results without confusing the server.
- t = transport.SvnRaTransport(url=url)
- svn.ra.get_log(t.ra, paths, start, end, limit,
- discover_changed_paths,
- strict_node_history,
- receiver)
- except SubversionException, (inst, num):
- pickle.dump(num, fp, protocol)
- except IOError:
- # Caller may interrupt the iteration
- pickle.dump(None, fp, protocol)
- else:
- pickle.dump(None, fp, protocol)
- fp.close()
- # With large history, cleanup process goes crazy and suddenly
- # consumes *huge* amount of memory. The output file being closed,
- # there is no need for clean termination.
- os._exit(0)
-
-def debugsvnlog(ui, **opts):
- """Fetch SVN log in a subprocess and channel them back to parent to
- avoid memory collection issues.
- """
- util.set_binary(sys.stdin)
- util.set_binary(sys.stdout)
- args = decodeargs(sys.stdin.read())
- get_log_child(sys.stdout, *args)
-
-class logstream(object):
- """Interruptible revision log iterator."""
- def __init__(self, stdout):
- self._stdout = stdout
-
- def __iter__(self):
- while True:
- try:
- entry = pickle.load(self._stdout)
- except EOFError:
- raise util.Abort(_('Mercurial failed to run itself, check'
- ' hg executable is in PATH'))
- try:
- orig_paths, revnum, author, date, message = entry
- except:
- if entry is None:
- break
- raise SubversionException("child raised exception", entry)
- yield entry
-
- def close(self):
- if self._stdout:
- self._stdout.close()
- self._stdout = None
-
-
-# Check to see if the given path is a local Subversion repo. Verify this by
-# looking for several svn-specific files and directories in the given
-# directory.
-def filecheck(ui, path, proto):
- for x in ('locks', 'hooks', 'format', 'db'):
- if not os.path.exists(os.path.join(path, x)):
- return False
- return True
-
-# Check to see if a given path is the root of an svn repo over http. We verify
-# this by requesting a version-controlled URL we know can't exist and looking
-# for the svn-specific "not found" XML.
-def httpcheck(ui, path, proto):
- try:
- opener = urllib2.build_opener()
- rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path))
- data = rsp.read()
- except urllib2.HTTPError, inst:
- if inst.code != 404:
- # Except for 404 we cannot know for sure this is not an svn repo
- ui.warn(_('svn: cannot probe remote repository, assume it could '
- 'be a subversion repository. Use --source-type if you '
- 'know better.\n'))
- return True
- data = inst.fp.read()
- except:
- # Could be urllib2.URLError if the URL is invalid or anything else.
- return False
- return '<m:human-readable errcode="160013">' in data
-
-protomap = {'http': httpcheck,
- 'https': httpcheck,
- 'file': filecheck,
- }
-def issvnurl(ui, url):
- try:
- proto, path = url.split('://', 1)
- if proto == 'file':
- path = urllib.url2pathname(path)
- except ValueError:
- proto = 'file'
- path = os.path.abspath(url)
- if proto == 'file':
- path = path.replace(os.sep, '/')
- check = protomap.get(proto, lambda *args: False)
- while '/' in path:
- if check(ui, path, proto):
- return True
- path = path.rsplit('/', 1)[0]
- return False
-
-# SVN conversion code stolen from bzr-svn and tailor
-#
-# Subversion looks like a versioned filesystem, branches structures
-# are defined by conventions and not enforced by the tool. First,
-# we define the potential branches (modules) as "trunk" and "branches"
-# children directories. Revisions are then identified by their
-# module and revision number (and a repository identifier).
-#
-# The revision graph is really a tree (or a forest). By default, a
-# revision parent is the previous revision in the same module. If the
-# module directory is copied/moved from another module then the
-# revision is the module root and its parent the source revision in
-# the parent module. A revision has at most one parent.
-#
-class svn_source(converter_source):
- def __init__(self, ui, url, rev=None):
- super(svn_source, self).__init__(ui, url, rev=rev)
-
- if not (url.startswith('svn://') or url.startswith('svn+ssh://') or
- (os.path.exists(url) and
- os.path.exists(os.path.join(url, '.svn'))) or
- issvnurl(ui, url)):
- raise NoRepo(_("%s does not look like a Subversion repository")
- % url)
-
- try:
- SubversionException
- except NameError:
- raise MissingTool(_('Subversion python bindings could not be loaded'))
-
- try:
- version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
- if version < (1, 4):
- raise MissingTool(_('Subversion python bindings %d.%d found, '
- '1.4 or later required') % version)
- except AttributeError:
- raise MissingTool(_('Subversion python bindings are too old, 1.4 '
- 'or later required'))
-
- self.lastrevs = {}
-
- latest = None
- try:
- # Support file://path@rev syntax. Useful e.g. to convert
- # deleted branches.
- at = url.rfind('@')
- if at >= 0:
- latest = int(url[at + 1:])
- url = url[:at]
- except ValueError:
- pass
- self.url = geturl(url)
- self.encoding = 'UTF-8' # Subversion is always nominal UTF-8
- try:
- self.transport = transport.SvnRaTransport(url=self.url)
- self.ra = self.transport.ra
- self.ctx = self.transport.client
- self.baseurl = svn.ra.get_repos_root(self.ra)
- # Module is either empty or a repository path starting with
- # a slash and not ending with a slash.
- self.module = urllib.unquote(self.url[len(self.baseurl):])
- self.prevmodule = None
- self.rootmodule = self.module
- self.commits = {}
- self.paths = {}
- self.uuid = svn.ra.get_uuid(self.ra)
- except SubversionException:
- ui.traceback()
- raise NoRepo(_("%s does not look like a Subversion repository")
- % self.url)
-
- if rev:
- try:
- latest = int(rev)
- except ValueError:
- raise util.Abort(_('svn: revision %s is not an integer') % rev)
-
- self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
- try:
- self.startrev = int(self.startrev)
- if self.startrev < 0:
- self.startrev = 0
- except ValueError:
- raise util.Abort(_('svn: start revision %s is not an integer')
- % self.startrev)
-
- self.head = self.latest(self.module, latest)
- if not self.head:
- raise util.Abort(_('no revision found in module %s')
- % self.module)
- self.last_changed = self.revnum(self.head)
-
- self._changescache = None
-
- if os.path.exists(os.path.join(url, '.svn/entries')):
- self.wc = url
- else:
- self.wc = None
- self.convertfp = None
-
- def setrevmap(self, revmap):
- lastrevs = {}
- for revid in revmap.iterkeys():
- uuid, module, revnum = self.revsplit(revid)
- lastrevnum = lastrevs.setdefault(module, revnum)
- if revnum > lastrevnum:
- lastrevs[module] = revnum
- self.lastrevs = lastrevs
-
- def exists(self, path, optrev):
- try:
- svn.client.ls(self.url.rstrip('/') + '/' + urllib.quote(path),
- optrev, False, self.ctx)
- return True
- except SubversionException:
- return False
-
- def getheads(self):
-
- def isdir(path, revnum):
- kind = self._checkpath(path, revnum)
- return kind == svn.core.svn_node_dir
-
- def getcfgpath(name, rev):
- cfgpath = self.ui.config('convert', 'svn.' + name)
- if cfgpath is not None and cfgpath.strip() == '':
- return None
- path = (cfgpath or name).strip('/')
- if not self.exists(path, rev):
- if cfgpath:
- raise util.Abort(_('expected %s to be at %r, but not found')
- % (name, path))
- return None
- self.ui.note(_('found %s at %r\n') % (name, path))
- return path
-
- rev = optrev(self.last_changed)
- oldmodule = ''
- trunk = getcfgpath('trunk', rev)
- self.tags = getcfgpath('tags', rev)
- branches = getcfgpath('branches', rev)
-
- # If the project has a trunk or branches, we will extract heads
- # from them. We keep the project root otherwise.
- if trunk:
- oldmodule = self.module or ''
- self.module += '/' + trunk
- self.head = self.latest(self.module, self.last_changed)
- if not self.head:
- raise util.Abort(_('no revision found in module %s')
- % self.module)
-
- # First head in the list is the module's head
- self.heads = [self.head]
- if self.tags is not None:
- self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
-
- # Check if branches bring a few more heads to the list
- if branches:
- rpath = self.url.strip('/')
- branchnames = svn.client.ls(rpath + '/' + urllib.quote(branches),
- rev, False, self.ctx)
- for branch in branchnames.keys():
- module = '%s/%s/%s' % (oldmodule, branches, branch)
- if not isdir(module, self.last_changed):
- continue
- brevid = self.latest(module, self.last_changed)
- if not brevid:
- self.ui.note(_('ignoring empty branch %s\n') % branch)
- continue
- self.ui.note(_('found branch %s at %d\n') %
- (branch, self.revnum(brevid)))
- self.heads.append(brevid)
-
- if self.startrev and self.heads:
- if len(self.heads) > 1:
- raise util.Abort(_('svn: start revision is not supported '
- 'with more than one branch'))
- revnum = self.revnum(self.heads[0])
- if revnum < self.startrev:
- raise util.Abort(
- _('svn: no revision found after start revision %d')
- % self.startrev)
-
- return self.heads
-
- def getchanges(self, rev):
- if self._changescache and self._changescache[0] == rev:
- return self._changescache[1]
- self._changescache = None
- (paths, parents) = self.paths[rev]
- if parents:
- files, self.removed, copies = self.expandpaths(rev, paths, parents)
- else:
- # Perform a full checkout on roots
- uuid, module, revnum = self.revsplit(rev)
- entries = svn.client.ls(self.baseurl + urllib.quote(module),
- optrev(revnum), True, self.ctx)
- files = [n for n, e in entries.iteritems()
- if e.kind == svn.core.svn_node_file]
- copies = {}
- self.removed = set()
-
- files.sort()
- files = zip(files, [rev] * len(files))
-
- # caller caches the result, so free it here to release memory
- del self.paths[rev]
- return (files, copies)
-
- def getchangedfiles(self, rev, i):
- changes = self.getchanges(rev)
- self._changescache = (rev, changes)
- return [f[0] for f in changes[0]]
-
- def getcommit(self, rev):
- if rev not in self.commits:
- uuid, module, revnum = self.revsplit(rev)
- self.module = module
- self.reparent(module)
- # We assume that:
- # - requests for revisions after "stop" come from the
- # revision graph backward traversal. Cache all of them
- # down to stop, they will be used eventually.
- # - requests for revisions before "stop" come to get
- # isolated branches parents. Just fetch what is needed.
- stop = self.lastrevs.get(module, 0)
- if revnum < stop:
- stop = revnum + 1
- self._fetch_revisions(revnum, stop)
- commit = self.commits[rev]
- # caller caches the result, so free it here to release memory
- del self.commits[rev]
- return commit
-
- def gettags(self):
- tags = {}
- if self.tags is None:
- return tags
-
- # svn tags are just a convention, project branches left in a
- # 'tags' directory. There is no other relationship than
- # ancestry, which is expensive to discover and makes them hard
- # to update incrementally. Worse, past revisions may be
- # referenced by tags far away in the future, requiring a deep
- # history traversal on every calculation. Current code
- # performs a single backward traversal, tracking moves within
- # the tags directory (tag renaming) and recording a new tag
- # everytime a project is copied from outside the tags
- # directory. It also lists deleted tags, this behaviour may
- # change in the future.
- pendings = []
- tagspath = self.tags
- start = svn.ra.get_latest_revnum(self.ra)
- stream = self._getlog([self.tags], start, self.startrev)
- try:
- for entry in stream:
- origpaths, revnum, author, date, message = entry
- copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
- in origpaths.iteritems() if e.copyfrom_path]
- # Apply moves/copies from more specific to general
- copies.sort(reverse=True)
-
- srctagspath = tagspath
- if copies and copies[-1][2] == tagspath:
- # Track tags directory moves
- srctagspath = copies.pop()[0]
-
- for source, sourcerev, dest in copies:
- if not dest.startswith(tagspath + '/'):
- continue
- for tag in pendings:
- if tag[0].startswith(dest):
- tagpath = source + tag[0][len(dest):]
- tag[:2] = [tagpath, sourcerev]
- break
- else:
- pendings.append([source, sourcerev, dest])
-
- # Filter out tags with children coming from different
- # parts of the repository like:
- # /tags/tag.1 (from /trunk:10)
- # /tags/tag.1/foo (from /branches/foo:12)
- # Here/tags/tag.1 discarded as well as its children.
- # It happens with tools like cvs2svn. Such tags cannot
- # be represented in mercurial.
- addeds = dict((p, e.copyfrom_path) for p, e
- in origpaths.iteritems()
- if e.action == 'A' and e.copyfrom_path)
- badroots = set()
- for destroot in addeds:
- for source, sourcerev, dest in pendings:
- if (not dest.startswith(destroot + '/')
- or source.startswith(addeds[destroot] + '/')):
- continue
- badroots.add(destroot)
- break
-
- for badroot in badroots:
- pendings = [p for p in pendings if p[2] != badroot
- and not p[2].startswith(badroot + '/')]
-
- # Tell tag renamings from tag creations
- remainings = []
- for source, sourcerev, dest in pendings:
- tagname = dest.split('/')[-1]
- if source.startswith(srctagspath):
- remainings.append([source, sourcerev, tagname])
- continue
- if tagname in tags:
- # Keep the latest tag value
- continue
- # From revision may be fake, get one with changes
- try:
- tagid = self.latest(source, sourcerev)
- if tagid and tagname not in tags:
- tags[tagname] = tagid
- except SvnPathNotFound:
- # It happens when we are following directories
- # we assumed were copied with their parents
- # but were really created in the tag
- # directory.
- pass
- pendings = remainings
- tagspath = srctagspath
- finally:
- stream.close()
- return tags
-
- def converted(self, rev, destrev):
- if not self.wc:
- return
- if self.convertfp is None:
- self.convertfp = open(os.path.join(self.wc, '.svn', 'hg-shamap'),
- 'a')
- self.convertfp.write('%s %d\n' % (destrev, self.revnum(rev)))
- self.convertfp.flush()
-
- def revid(self, revnum, module=None):
- return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum)
-
- def revnum(self, rev):
- return int(rev.split('@')[-1])
-
- def revsplit(self, rev):
- url, revnum = rev.rsplit('@', 1)
- revnum = int(revnum)
- parts = url.split('/', 1)
- uuid = parts.pop(0)[4:]
- mod = ''
- if parts:
- mod = '/' + parts[0]
- return uuid, mod, revnum
-
- def latest(self, path, stop=0):
- """Find the latest revid affecting path, up to stop. It may return
- a revision in a different module, since a branch may be moved without
- a change being reported. Return None if computed module does not
- belong to rootmodule subtree.
- """
- if not path.startswith(self.rootmodule):
- # Requests on foreign branches may be forbidden at server level
- self.ui.debug('ignoring foreign branch %r\n' % path)
- return None
-
- if not stop:
- stop = svn.ra.get_latest_revnum(self.ra)
- try:
- prevmodule = self.reparent('')
- dirent = svn.ra.stat(self.ra, path.strip('/'), stop)
- self.reparent(prevmodule)
- except SubversionException:
- dirent = None
- if not dirent:
- raise SvnPathNotFound(_('%s not found up to revision %d')
- % (path, stop))
-
- # stat() gives us the previous revision on this line of
- # development, but it might be in *another module*. Fetch the
- # log and detect renames down to the latest revision.
- stream = self._getlog([path], stop, dirent.created_rev)
- try:
- for entry in stream:
- paths, revnum, author, date, message = entry
- if revnum <= dirent.created_rev:
- break
-
- for p in paths:
- if not path.startswith(p) or not paths[p].copyfrom_path:
- continue
- newpath = paths[p].copyfrom_path + path[len(p):]
- self.ui.debug("branch renamed from %s to %s at %d\n" %
- (path, newpath, revnum))
- path = newpath
- break
- finally:
- stream.close()
-
- if not path.startswith(self.rootmodule):
- self.ui.debug('ignoring foreign branch %r\n' % path)
- return None
- return self.revid(dirent.created_rev, path)
-
- def reparent(self, module):
- """Reparent the svn transport and return the previous parent."""
- if self.prevmodule == module:
- return module
- svnurl = self.baseurl + urllib.quote(module)
- prevmodule = self.prevmodule
- if prevmodule is None:
- prevmodule = ''
- self.ui.debug("reparent to %s\n" % svnurl)
- svn.ra.reparent(self.ra, svnurl)
- self.prevmodule = module
- return prevmodule
-
- def expandpaths(self, rev, paths, parents):
- changed, removed = set(), set()
- copies = {}
-
- new_module, revnum = self.revsplit(rev)[1:]
- if new_module != self.module:
- self.module = new_module
- self.reparent(self.module)
-
- for i, (path, ent) in enumerate(paths):
- self.ui.progress(_('scanning paths'), i, item=path,
- total=len(paths))
- entrypath = self.getrelpath(path)
-
- kind = self._checkpath(entrypath, revnum)
- if kind == svn.core.svn_node_file:
- changed.add(self.recode(entrypath))
- if not ent.copyfrom_path or not parents:
- continue
- # Copy sources not in parent revisions cannot be
- # represented, ignore their origin for now
- pmodule, prevnum = self.revsplit(parents[0])[1:]
- if ent.copyfrom_rev < prevnum:
- continue
- copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
- if not copyfrom_path:
- continue
- self.ui.debug("copied to %s from %s@%s\n" %
- (entrypath, copyfrom_path, ent.copyfrom_rev))
- copies[self.recode(entrypath)] = self.recode(copyfrom_path)
- elif kind == 0: # gone, but had better be a deleted *file*
- self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
- pmodule, prevnum = self.revsplit(parents[0])[1:]
- parentpath = pmodule + "/" + entrypath
- fromkind = self._checkpath(entrypath, prevnum, pmodule)
-
- if fromkind == svn.core.svn_node_file:
- removed.add(self.recode(entrypath))
- elif fromkind == svn.core.svn_node_dir:
- oroot = parentpath.strip('/')
- nroot = path.strip('/')
- children = self._iterfiles(oroot, prevnum)
- for childpath in children:
- childpath = childpath.replace(oroot, nroot)
- childpath = self.getrelpath("/" + childpath, pmodule)
- if childpath:
- removed.add(self.recode(childpath))
- else:
- self.ui.debug('unknown path in revision %d: %s\n' % \
- (revnum, path))
- elif kind == svn.core.svn_node_dir:
- if ent.action == 'M':
- # If the directory just had a prop change,
- # then we shouldn't need to look for its children.
- continue
- if ent.action == 'R' and parents:
- # If a directory is replacing a file, mark the previous
- # file as deleted
- pmodule, prevnum = self.revsplit(parents[0])[1:]
- pkind = self._checkpath(entrypath, prevnum, pmodule)
- if pkind == svn.core.svn_node_file:
- removed.add(self.recode(entrypath))
- elif pkind == svn.core.svn_node_dir:
- # We do not know what files were kept or removed,
- # mark them all as changed.
- for childpath in self._iterfiles(pmodule, prevnum):
- childpath = self.getrelpath("/" + childpath)
- if childpath:
- changed.add(self.recode(childpath))
-
- for childpath in self._iterfiles(path, revnum):
- childpath = self.getrelpath("/" + childpath)
- if childpath:
- changed.add(self.recode(childpath))
-
- # Handle directory copies
- if not ent.copyfrom_path or not parents:
- continue
- # Copy sources not in parent revisions cannot be
- # represented, ignore their origin for now
- pmodule, prevnum = self.revsplit(parents[0])[1:]
- if ent.copyfrom_rev < prevnum:
- continue
- copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
- if not copyfrompath:
- continue
- self.ui.debug("mark %s came from %s:%d\n"
- % (path, copyfrompath, ent.copyfrom_rev))
- children = self._iterfiles(ent.copyfrom_path, ent.copyfrom_rev)
- for childpath in children:
- childpath = self.getrelpath("/" + childpath, pmodule)
- if not childpath:
- continue
- copytopath = path + childpath[len(copyfrompath):]
- copytopath = self.getrelpath(copytopath)
- copies[self.recode(copytopath)] = self.recode(childpath)
-
- self.ui.progress(_('scanning paths'), None)
- changed.update(removed)
- return (list(changed), removed, copies)
-
- def _fetch_revisions(self, from_revnum, to_revnum):
- if from_revnum < to_revnum:
- from_revnum, to_revnum = to_revnum, from_revnum
-
- self.child_cset = None
-
- def parselogentry(orig_paths, revnum, author, date, message):
- """Return the parsed commit object or None, and True if
- the revision is a branch root.
- """
- self.ui.debug("parsing revision %d (%d changes)\n" %
- (revnum, len(orig_paths)))
-
- branched = False
- rev = self.revid(revnum)
- # branch log might return entries for a parent we already have
-
- if rev in self.commits or revnum < to_revnum:
- return None, branched
-
- parents = []
- # check whether this revision is the start of a branch or part
- # of a branch renaming
- orig_paths = sorted(orig_paths.iteritems())
- root_paths = [(p, e) for p, e in orig_paths
- if self.module.startswith(p)]
- if root_paths:
- path, ent = root_paths[-1]
- if ent.copyfrom_path:
- branched = True
- newpath = ent.copyfrom_path + self.module[len(path):]
- # ent.copyfrom_rev may not be the actual last revision
- previd = self.latest(newpath, ent.copyfrom_rev)
- if previd is not None:
- prevmodule, prevnum = self.revsplit(previd)[1:]
- if prevnum >= self.startrev:
- parents = [previd]
- self.ui.note(
- _('found parent of branch %s at %d: %s\n') %
- (self.module, prevnum, prevmodule))
- else:
- self.ui.debug("no copyfrom path, don't know what to do.\n")
-
- paths = []
- # filter out unrelated paths
- for path, ent in orig_paths:
- if self.getrelpath(path) is None:
- continue
- paths.append((path, ent))
-
- # Example SVN datetime. Includes microseconds.
- # ISO-8601 conformant
- # '2007-01-04T17:35:00.902377Z'
- date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
-
- log = message and self.recode(message) or ''
- author = author and self.recode(author) or ''
- try:
- branch = self.module.split("/")[-1]
- if branch == 'trunk':
- branch = ''
- except IndexError:
- branch = None
-
- cset = commit(author=author,
- date=util.datestr(date),
- desc=log,
- parents=parents,
- branch=branch,
- rev=rev)
-
- self.commits[rev] = cset
- # The parents list is *shared* among self.paths and the
- # commit object. Both will be updated below.
- self.paths[rev] = (paths, cset.parents)
- if self.child_cset and not self.child_cset.parents:
- self.child_cset.parents[:] = [rev]
- self.child_cset = cset
- return cset, branched
-
- self.ui.note(_('fetching revision log for "%s" from %d to %d\n') %
- (self.module, from_revnum, to_revnum))
-
- try:
- firstcset = None
- lastonbranch = False
- stream = self._getlog([self.module], from_revnum, to_revnum)
- try:
- for entry in stream:
- paths, revnum, author, date, message = entry
- if revnum < self.startrev:
- lastonbranch = True
- break
- if not paths:
- self.ui.debug('revision %d has no entries\n' % revnum)
- # If we ever leave the loop on an empty
- # revision, do not try to get a parent branch
- lastonbranch = lastonbranch or revnum == 0
- continue
- cset, lastonbranch = parselogentry(paths, revnum, author,
- date, message)
- if cset:
- firstcset = cset
- if lastonbranch:
- break
- finally:
- stream.close()
-
- if not lastonbranch and firstcset and not firstcset.parents:
- # The first revision of the sequence (the last fetched one)
- # has invalid parents if not a branch root. Find the parent
- # revision now, if any.
- try:
- firstrevnum = self.revnum(firstcset.rev)
- if firstrevnum > 1:
- latest = self.latest(self.module, firstrevnum - 1)
- if latest:
- firstcset.parents.append(latest)
- except SvnPathNotFound:
- pass
- except SubversionException, (inst, num):
- if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
- raise util.Abort(_('svn: branch has no revision %s') % to_revnum)
- raise
-
- def getfile(self, file, rev):
- # TODO: ra.get_file transmits the whole file instead of diffs.
- if file in self.removed:
- raise IOError()
- mode = ''
- try:
- new_module, revnum = self.revsplit(rev)[1:]
- if self.module != new_module:
- self.module = new_module
- self.reparent(self.module)
- io = StringIO()
- info = svn.ra.get_file(self.ra, file, revnum, io)
- data = io.getvalue()
- # ra.get_files() seems to keep a reference on the input buffer
- # preventing collection. Release it explicitely.
- io.close()
- if isinstance(info, list):
- info = info[-1]
- mode = ("svn:executable" in info) and 'x' or ''
- mode = ("svn:special" in info) and 'l' or mode
- except SubversionException, e:
- notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
- svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
- if e.apr_err in notfound: # File not found
- raise IOError()
- raise
- if mode == 'l':
- link_prefix = "link "
- if data.startswith(link_prefix):
- data = data[len(link_prefix):]
- return data, mode
-
- def _iterfiles(self, path, revnum):
- """Enumerate all files in path at revnum, recursively."""
- path = path.strip('/')
- pool = Pool()
- rpath = '/'.join([self.baseurl, urllib.quote(path)]).strip('/')
- entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool)
- return ((path + '/' + p) for p, e in entries.iteritems()
- if e.kind == svn.core.svn_node_file)
-
- def getrelpath(self, path, module=None):
- if module is None:
- module = self.module
- # Given the repository url of this wc, say
- # "http://server/plone/CMFPlone/branches/Plone-2_0-branch"
- # extract the "entry" portion (a relative path) from what
- # svn log --xml says, ie
- # "/CMFPlone/branches/Plone-2_0-branch/tests/PloneTestCase.py"
- # that is to say "tests/PloneTestCase.py"
- if path.startswith(module):
- relative = path.rstrip('/')[len(module):]
- if relative.startswith('/'):
- return relative[1:]
- elif relative == '':
- return relative
-
- # The path is outside our tracked tree...
- self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
- return None
-
- def _checkpath(self, path, revnum, module=None):
- if module is not None:
- prevmodule = self.reparent('')
- path = module + '/' + path
- try:
- # ra.check_path does not like leading slashes very much, it leads
- # to PROPFIND subversion errors
- return svn.ra.check_path(self.ra, path.strip('/'), revnum)
- finally:
- if module is not None:
- self.reparent(prevmodule)
-
- def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True,
- strict_node_history=False):
- # Normalize path names, svn >= 1.5 only wants paths relative to
- # supplied URL
- relpaths = []
- for p in paths:
- if not p.startswith('/'):
- p = self.module + '/' + p
- relpaths.append(p.strip('/'))
- args = [self.baseurl, relpaths, start, end, limit, discover_changed_paths,
- strict_node_history]
- arg = encodeargs(args)
- hgexe = util.hgexecutable()
- cmd = '%s debugsvnlog' % util.shellquote(hgexe)
- stdin, stdout = util.popen2(cmd)
- stdin.write(arg)
- try:
- stdin.close()
- except IOError:
- raise util.Abort(_('Mercurial failed to run itself, check'
- ' hg executable is in PATH'))
- return logstream(stdout)
-
-pre_revprop_change = '''#!/bin/sh
-
-REPOS="$1"
-REV="$2"
-USER="$3"
-PROPNAME="$4"
-ACTION="$5"
-
-if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
-if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-branch" ]; then exit 0; fi
-if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-rev" ]; then exit 0; fi
-
-echo "Changing prohibited revision property" >&2
-exit 1
-'''
-
-class svn_sink(converter_sink, commandline):
- commit_re = re.compile(r'Committed revision (\d+).', re.M)
-
- def prerun(self):
- if self.wc:
- os.chdir(self.wc)
-
- def postrun(self):
- if self.wc:
- os.chdir(self.cwd)
-
- def join(self, name):
- return os.path.join(self.wc, '.svn', name)
-
- def revmapfile(self):
- return self.join('hg-shamap')
-
- def authorfile(self):
- return self.join('hg-authormap')
-
- def __init__(self, ui, path):
- converter_sink.__init__(self, ui, path)
- commandline.__init__(self, ui, 'svn')
- self.delete = []
- self.setexec = []
- self.delexec = []
- self.copies = []
- self.wc = None
- self.cwd = os.getcwd()
-
- path = os.path.realpath(path)
-
- created = False
- if os.path.isfile(os.path.join(path, '.svn', 'entries')):
- self.wc = path
- self.run0('update')
- else:
- wcpath = os.path.join(os.getcwd(), os.path.basename(path) + '-wc')
-
- if os.path.isdir(os.path.dirname(path)):
- if not os.path.exists(os.path.join(path, 'db', 'fs-type')):
- ui.status(_('initializing svn repository %r\n') %
- os.path.basename(path))
- commandline(ui, 'svnadmin').run0('create', path)
- created = path
- path = util.normpath(path)
- if not path.startswith('/'):
- path = '/' + path
- path = 'file://' + path
-
- ui.status(_('initializing svn working copy %r\n')
- % os.path.basename(wcpath))
- self.run0('checkout', path, wcpath)
-
- self.wc = wcpath
- self.opener = util.opener(self.wc)
- self.wopener = util.opener(self.wc)
- self.childmap = mapfile(ui, self.join('hg-childmap'))
- self.is_exec = util.checkexec(self.wc) and util.is_exec or None
-
- if created:
- hook = os.path.join(created, 'hooks', 'pre-revprop-change')
- fp = open(hook, 'w')
- fp.write(pre_revprop_change)
- fp.close()
- util.set_flags(hook, False, True)
-
- xport = transport.SvnRaTransport(url=geturl(path))
- self.uuid = svn.ra.get_uuid(xport.ra)
-
- def wjoin(self, *names):
- return os.path.join(self.wc, *names)
-
- def putfile(self, filename, flags, data):
- if 'l' in flags:
- self.wopener.symlink(data, filename)
- else:
- try:
- if os.path.islink(self.wjoin(filename)):
- os.unlink(filename)
- except OSError:
- pass
- self.wopener(filename, 'w').write(data)
-
- if self.is_exec:
- was_exec = self.is_exec(self.wjoin(filename))
- else:
- # On filesystems not supporting execute-bit, there is no way
- # to know if it is set but asking subversion. Setting it
- # systematically is just as expensive and much simpler.
- was_exec = 'x' not in flags
-
- util.set_flags(self.wjoin(filename), False, 'x' in flags)
- if was_exec:
- if 'x' not in flags:
- self.delexec.append(filename)
- else:
- if 'x' in flags:
- self.setexec.append(filename)
-
- def _copyfile(self, source, dest):
- # SVN's copy command pukes if the destination file exists, but
- # our copyfile method expects to record a copy that has
- # already occurred. Cross the semantic gap.
- wdest = self.wjoin(dest)
- exists = os.path.lexists(wdest)
- if exists:
- fd, tempname = tempfile.mkstemp(
- prefix='hg-copy-', dir=os.path.dirname(wdest))
- os.close(fd)
- os.unlink(tempname)
- os.rename(wdest, tempname)
- try:
- self.run0('copy', source, dest)
- finally:
- if exists:
- try:
- os.unlink(wdest)
- except OSError:
- pass
- os.rename(tempname, wdest)
-
- def dirs_of(self, files):
- dirs = set()
- for f in files:
- if os.path.isdir(self.wjoin(f)):
- dirs.add(f)
- for i in strutil.rfindall(f, '/'):
- dirs.add(f[:i])
- return dirs
-
- def add_dirs(self, files):
- add_dirs = [d for d in sorted(self.dirs_of(files))
- if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
- if add_dirs:
- self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
- return add_dirs
-
- def add_files(self, files):
- if files:
- self.xargs(files, 'add', quiet=True)
- return files
-
- def tidy_dirs(self, names):
- deleted = []
- for d in sorted(self.dirs_of(names), reverse=True):
- wd = self.wjoin(d)
- if os.listdir(wd) == '.svn':
- self.run0('delete', d)
- deleted.append(d)
- return deleted
-
- def addchild(self, parent, child):
- self.childmap[parent] = child
-
- def revid(self, rev):
- return u"svn:%s@%s" % (self.uuid, rev)
-
- def putcommit(self, files, copies, parents, commit, source, revmap):
- # Apply changes to working copy
- for f, v in files:
- try:
- data, mode = source.getfile(f, v)
- except IOError:
- self.delete.append(f)
- else:
- self.putfile(f, mode, data)
- if f in copies:
- self.copies.append([copies[f], f])
- files = [f[0] for f in files]
-
- for parent in parents:
- try:
- return self.revid(self.childmap[parent])
- except KeyError:
- pass
- entries = set(self.delete)
- files = frozenset(files)
- entries.update(self.add_dirs(files.difference(entries)))
- if self.copies:
- for s, d in self.copies:
- self._copyfile(s, d)
- self.copies = []
- if self.delete:
- self.xargs(self.delete, 'delete')
- self.delete = []
- entries.update(self.add_files(files.difference(entries)))
- entries.update(self.tidy_dirs(entries))
- if self.delexec:
- self.xargs(self.delexec, 'propdel', 'svn:executable')
- self.delexec = []
- if self.setexec:
- self.xargs(self.setexec, 'propset', 'svn:executable', '*')
- self.setexec = []
-
- fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
- fp = os.fdopen(fd, 'w')
- fp.write(commit.desc)
- fp.close()
- try:
- output = self.run0('commit',
- username=util.shortuser(commit.author),
- file=messagefile,
- encoding='utf-8')
- try:
- rev = self.commit_re.search(output).group(1)
- except AttributeError:
- if not files:
- return parents[0]
- self.ui.warn(_('unexpected svn output:\n'))
- self.ui.warn(output)
- raise util.Abort(_('unable to cope with svn output'))
- if commit.rev:
- self.run('propset', 'hg:convert-rev', commit.rev,
- revprop=True, revision=rev)
- if commit.branch and commit.branch != 'default':
- self.run('propset', 'hg:convert-branch', commit.branch,
- revprop=True, revision=rev)
- for parent in parents:
- self.addchild(parent, rev)
- return self.revid(rev)
- finally:
- os.unlink(messagefile)
-
- def puttags(self, tags):
- self.ui.warn(_('writing Subversion tags is not yet implemented\n'))
- return None, None
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.pyo
deleted file mode 100644
index df675f8..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/subversion.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.py
deleted file mode 100644
index db68ede..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2007 Daniel Holth <dholth@fastmail.fm>
-# This is a stripped-down version of the original bzr-svn transport.py,
-# Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org>
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-from svn.core import SubversionException, Pool
-import svn.ra
-import svn.client
-import svn.core
-
-# Some older versions of the Python bindings need to be
-# explicitly initialized. But what we want to do probably
-# won't work worth a darn against those libraries anyway!
-svn.ra.initialize()
-
-svn_config = svn.core.svn_config_get_config(None)
-
-
-def _create_auth_baton(pool):
- """Create a Subversion authentication baton. """
- import svn.client
- # Give the client context baton a suite of authentication
- # providers.h
- providers = [
- svn.client.get_simple_provider(pool),
- svn.client.get_username_provider(pool),
- svn.client.get_ssl_client_cert_file_provider(pool),
- svn.client.get_ssl_client_cert_pw_file_provider(pool),
- svn.client.get_ssl_server_trust_file_provider(pool),
- ]
- # Platform-dependant authentication methods
- getprovider = getattr(svn.core, 'svn_auth_get_platform_specific_provider',
- None)
- if getprovider:
- # Available in svn >= 1.6
- for name in ('gnome_keyring', 'keychain', 'kwallet', 'windows'):
- for type in ('simple', 'ssl_client_cert_pw', 'ssl_server_trust'):
- p = getprovider(name, type, pool)
- if p:
- providers.append(p)
- else:
- if hasattr(svn.client, 'get_windows_simple_provider'):
- providers.append(svn.client.get_windows_simple_provider(pool))
-
- return svn.core.svn_auth_open(providers, pool)
-
-class NotBranchError(SubversionException):
- pass
-
-class SvnRaTransport(object):
- """
- Open an ra connection to a Subversion repository.
- """
- def __init__(self, url="", ra=None):
- self.pool = Pool()
- self.svn_url = url
- self.username = ''
- self.password = ''
-
- # Only Subversion 1.4 has reparent()
- if ra is None or not hasattr(svn.ra, 'reparent'):
- self.client = svn.client.create_context(self.pool)
- ab = _create_auth_baton(self.pool)
- if False:
- svn.core.svn_auth_set_parameter(
- ab, svn.core.SVN_AUTH_PARAM_DEFAULT_USERNAME, self.username)
- svn.core.svn_auth_set_parameter(
- ab, svn.core.SVN_AUTH_PARAM_DEFAULT_PASSWORD, self.password)
- self.client.auth_baton = ab
- self.client.config = svn_config
- try:
- self.ra = svn.client.open_ra_session(
- self.svn_url.encode('utf8'),
- self.client, self.pool)
- except SubversionException, (inst, num):
- if num in (svn.core.SVN_ERR_RA_ILLEGAL_URL,
- svn.core.SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED,
- svn.core.SVN_ERR_BAD_URL):
- raise NotBranchError(url)
- raise
- else:
- self.ra = ra
- svn.ra.reparent(self.ra, self.svn_url.encode('utf8'))
-
- class Reporter(object):
- def __init__(self, reporter_data):
- self._reporter, self._baton = reporter_data
-
- def set_path(self, path, revnum, start_empty, lock_token, pool=None):
- svn.ra.reporter2_invoke_set_path(self._reporter, self._baton,
- path, revnum, start_empty, lock_token, pool)
-
- def delete_path(self, path, pool=None):
- svn.ra.reporter2_invoke_delete_path(self._reporter, self._baton,
- path, pool)
-
- def link_path(self, path, url, revision, start_empty, lock_token,
- pool=None):
- svn.ra.reporter2_invoke_link_path(self._reporter, self._baton,
- path, url, revision, start_empty, lock_token,
- pool)
-
- def finish_report(self, pool=None):
- svn.ra.reporter2_invoke_finish_report(self._reporter,
- self._baton, pool)
-
- def abort_report(self, pool=None):
- svn.ra.reporter2_invoke_abort_report(self._reporter,
- self._baton, pool)
-
- def do_update(self, revnum, path, *args, **kwargs):
- return self.Reporter(svn.ra.do_update(self.ra, revnum, path,
- *args, **kwargs))
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.pyo
deleted file mode 100644
index ee1d3d1..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/convert/transport.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.py
deleted file mode 100644
index 88294a7..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.py
+++ /dev/null
@@ -1,272 +0,0 @@
-"""automatically manage newlines in repository files
-
-This extension allows you to manage the type of line endings (CRLF or
-LF) that are used in the repository and in the local working
-directory. That way you can get CRLF line endings on Windows and LF on
-Unix/Mac, thereby letting everybody use their OS native line endings.
-
-The extension reads its configuration from a versioned ``.hgeol``
-configuration file every time you run an ``hg`` command. The
-``.hgeol`` file use the same syntax as all other Mercurial
-configuration files. It uses two sections, ``[patterns]`` and
-``[repository]``.
-
-The ``[patterns]`` section specifies how line endings should be
-converted between the working copy and the repository. The format is
-specified by a file pattern. The first match is used, so put more
-specific patterns first. The available line endings are ``LF``,
-``CRLF``, and ``BIN``.
-
-Files with the declared format of ``CRLF`` or ``LF`` are always
-checked out and stored in the repository in that format and files
-declared to be binary (``BIN``) are left unchanged. Additionally,
-``native`` is an alias for checking out in the platform's default line
-ending: ``LF`` on Unix (including Mac OS X) and ``CRLF`` on
-Windows. Note that ``BIN`` (do nothing to line endings) is Mercurial's
-default behaviour; it is only needed if you need to override a later,
-more general pattern.
-
-The optional ``[repository]`` section specifies the line endings to
-use for files stored in the repository. It has a single setting,
-``native``, which determines the storage line endings for files
-declared as ``native`` in the ``[patterns]`` section. It can be set to
-``LF`` or ``CRLF``. The default is ``LF``. For example, this means
-that on Windows, files configured as ``native`` (``CRLF`` by default)
-will be converted to ``LF`` when stored in the repository. Files
-declared as ``LF``, ``CRLF``, or ``BIN`` in the ``[patterns]`` section
-are always stored as-is in the repository.
-
-Example versioned ``.hgeol`` file::
-
- [patterns]
- **.py = native
- **.vcproj = CRLF
- **.txt = native
- Makefile = LF
- **.jpg = BIN
-
- [repository]
- native = LF
-
-.. note::
- The rules will first apply when files are touched in the working
- copy, e.g. by updating to null and back to tip to touch all files.
-
-The extension uses an optional ``[eol]`` section in your hgrc file
-(not the ``.hgeol`` file) for settings that control the overall
-behavior. There are two settings:
-
-- ``eol.native`` (default ``os.linesep``) can be set to ``LF`` or
- ``CRLF`` to override the default interpretation of ``native`` for
- checkout. This can be used with :hg:`archive` on Unix, say, to
- generate an archive where files have line endings for Windows.
-
-- ``eol.only-consistent`` (default True) can be set to False to make
- the extension convert files with inconsistent EOLs. Inconsistent
- means that there is both ``CRLF`` and ``LF`` present in the file.
- Such files are normally not touched under the assumption that they
- have mixed EOLs on purpose.
-
-The ``win32text.forbid*`` hooks provided by the win32text extension
-have been unified into a single hook named ``eol.hook``. The hook will
-lookup the expected line endings from the ``.hgeol`` file, which means
-you must migrate to a ``.hgeol`` file first before using the hook.
-
-See :hg:`help patterns` for more information about the glob patterns
-used.
-"""
-
-from mercurial.i18n import _
-from mercurial import util, config, extensions, match
-import re, os
-
-# Matches a lone LF, i.e., one that is not part of CRLF.
-singlelf = re.compile('(^|[^\r])\n')
-# Matches a single EOL which can either be a CRLF where repeated CR
-# are removed or a LF. We do not care about old Machintosh files, so a
-# stray CR is an error.
-eolre = re.compile('\r*\n')
-
-
-def inconsistenteol(data):
- return '\r\n' in data and singlelf.search(data)
-
-def tolf(s, params, ui, **kwargs):
- """Filter to convert to LF EOLs."""
- if util.binary(s):
- return s
- if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
- return s
- return eolre.sub('\n', s)
-
-def tocrlf(s, params, ui, **kwargs):
- """Filter to convert to CRLF EOLs."""
- if util.binary(s):
- return s
- if ui.configbool('eol', 'only-consistent', True) and inconsistenteol(s):
- return s
- return eolre.sub('\r\n', s)
-
-def isbinary(s, params):
- """Filter to do nothing with the file."""
- return s
-
-filters = {
- 'to-lf': tolf,
- 'to-crlf': tocrlf,
- 'is-binary': isbinary,
-}
-
-
-def hook(ui, repo, node, hooktype, **kwargs):
- """verify that files have expected EOLs"""
- files = set()
- for rev in xrange(repo[node].rev(), len(repo)):
- files.update(repo[rev].files())
- tip = repo['tip']
- for f in files:
- if f not in tip:
- continue
- for pattern, target in ui.configitems('encode'):
- if match.match(repo.root, '', [pattern])(f):
- data = tip[f].data()
- if target == "to-lf" and "\r\n" in data:
- raise util.Abort(_("%s should not have CRLF line endings")
- % f)
- elif target == "to-crlf" and singlelf.search(data):
- raise util.Abort(_("%s should not have LF line endings")
- % f)
-
-
-def preupdate(ui, repo, hooktype, parent1, parent2):
- #print "preupdate for %s: %s -> %s" % (repo.root, parent1, parent2)
- repo.readhgeol(parent1)
- return False
-
-def uisetup(ui):
- ui.setconfig('hooks', 'preupdate.eol', preupdate)
-
-def extsetup(ui):
- try:
- extensions.find('win32text')
- raise util.Abort(_("the eol extension is incompatible with the "
- "win32text extension"))
- except KeyError:
- pass
-
-
-def reposetup(ui, repo):
- uisetup(repo.ui)
- #print "reposetup for", repo.root
-
- if not repo.local():
- return
- for name, fn in filters.iteritems():
- repo.adddatafilter(name, fn)
-
- ui.setconfig('patch', 'eol', 'auto')
-
- class eolrepo(repo.__class__):
-
- _decode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
- _encode = {'LF': 'to-lf', 'CRLF': 'to-crlf', 'BIN': 'is-binary'}
-
- def readhgeol(self, node=None, data=None):
- if data is None:
- try:
- if node is None:
- data = self.wfile('.hgeol').read()
- else:
- data = self[node]['.hgeol'].data()
- except (IOError, LookupError):
- return None
-
- if self.ui.config('eol', 'native', os.linesep) in ('LF', '\n'):
- self._decode['NATIVE'] = 'to-lf'
- else:
- self._decode['NATIVE'] = 'to-crlf'
-
- eol = config.config()
- # Our files should not be touched. The pattern must be
- # inserted first override a '** = native' pattern.
- eol.set('patterns', '.hg*', 'BIN')
- # We can then parse the user's patterns.
- eol.parse('.hgeol', data)
-
- if eol.get('repository', 'native') == 'CRLF':
- self._encode['NATIVE'] = 'to-crlf'
- else:
- self._encode['NATIVE'] = 'to-lf'
-
- for pattern, style in eol.items('patterns'):
- key = style.upper()
- try:
- self.ui.setconfig('decode', pattern, self._decode[key])
- self.ui.setconfig('encode', pattern, self._encode[key])
- except KeyError:
- self.ui.warn(_("ignoring unknown EOL style '%s' from %s\n")
- % (style, eol.source('patterns', pattern)))
-
- include = []
- exclude = []
- for pattern, style in eol.items('patterns'):
- key = style.upper()
- if key == 'BIN':
- exclude.append(pattern)
- else:
- include.append(pattern)
-
- # This will match the files for which we need to care
- # about inconsistent newlines.
- return match.match(self.root, '', [], include, exclude)
-
- def _hgcleardirstate(self):
- self._eolfile = self.readhgeol() or self.readhgeol('tip')
-
- if not self._eolfile:
- self._eolfile = util.never
- return
-
- try:
- cachemtime = os.path.getmtime(self.join("eol.cache"))
- except OSError:
- cachemtime = 0
-
- try:
- eolmtime = os.path.getmtime(self.wjoin(".hgeol"))
- except OSError:
- eolmtime = 0
-
- if eolmtime > cachemtime:
- ui.debug("eol: detected change in .hgeol\n")
- # TODO: we could introduce a method for this in dirstate.
- wlock = None
- try:
- wlock = self.wlock()
- for f, e in self.dirstate._map.iteritems():
- self.dirstate._map[f] = (e[0], e[1], -1, 0)
- self.dirstate._dirty = True
- # Touch the cache to update mtime. TODO: are we sure this
- # always enought to update the mtime, or should we write a
- # bit to the file?
- self.opener("eol.cache", "w").close()
- finally:
- if wlock is not None:
- wlock.release()
-
- def commitctx(self, ctx, error=False):
- for f in sorted(ctx.added() + ctx.modified()):
- if not self._eolfile(f):
- continue
- data = ctx[f].data()
- if util.binary(data):
- # We should not abort here, since the user should
- # be able to say "** = native" to automatically
- # have all non-binary files taken care of.
- continue
- if inconsistenteol(data):
- raise util.Abort(_("inconsistent newline style "
- "in %s\n" % f))
- return super(eolrepo, self).commitctx(ctx, error)
- repo.__class__ = eolrepo
- repo._hgcleardirstate()
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.pyo
deleted file mode 100644
index cd15b4f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/eol.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.py
deleted file mode 100644
index 5cf9f03..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.py
+++ /dev/null
@@ -1,325 +0,0 @@
-# extdiff.py - external diff program support for mercurial
-#
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to allow external programs to compare revisions
-
-The extdiff Mercurial extension allows you to use external programs
-to compare revisions, or revision with working directory. The external
-diff programs are called with a configurable set of options and two
-non-option arguments: paths to directories containing snapshots of
-files to compare.
-
-The extdiff extension also allows to configure new diff commands, so
-you do not need to type :hg:`extdiff -p kdiff3` always. ::
-
- [extdiff]
- # add new command that runs GNU diff(1) in 'context diff' mode
- cdiff = gdiff -Nprc5
- ## or the old way:
- #cmd.cdiff = gdiff
- #opts.cdiff = -Nprc5
-
- # add new command called vdiff, runs kdiff3
- vdiff = kdiff3
-
- # add new command called meld, runs meld (no need to name twice)
- meld =
-
- # add new command called vimdiff, runs gvimdiff with DirDiff plugin
- # (see http://www.vim.org/scripts/script.php?script_id=102) Non
- # English user, be sure to put "let g:DirDiffDynamicDiffText = 1" in
- # your .vimrc
- vimdiff = gvim -f '+next' '+execute "DirDiff" argv(0) argv(1)'
-
-Tool arguments can include variables that are expanded at runtime::
-
- $parent1, $plabel1 - filename, descriptive label of first parent
- $child, $clabel - filename, descriptive label of child revision
- $parent2, $plabel2 - filename, descriptive label of second parent
- $parent is an alias for $parent1.
-
-The extdiff extension will look in your [diff-tools] and [merge-tools]
-sections for diff tool arguments, when none are specified in [extdiff].
-
-::
-
- [extdiff]
- kdiff3 =
-
- [diff-tools]
- kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
-
-You can use -I/-X and list of file or directory names like normal
-:hg:`diff` command. The extdiff extension makes snapshots of only
-needed files, so running the external diff program will actually be
-pretty fast (at least faster than having to compare the entire tree).
-'''
-
-from mercurial.i18n import _
-from mercurial.node import short, nullid
-from mercurial import cmdutil, util, commands, encoding
-import os, shlex, shutil, tempfile, re
-
-def snapshot(ui, repo, files, node, tmproot):
- '''snapshot files as of some revision
- if not using snapshot, -I/-X does not work and recursive diff
- in tools like kdiff3 and meld displays too many files.'''
- dirname = os.path.basename(repo.root)
- if dirname == "":
- dirname = "root"
- if node is not None:
- dirname = '%s.%s' % (dirname, short(node))
- base = os.path.join(tmproot, dirname)
- os.mkdir(base)
- if node is not None:
- ui.note(_('making snapshot of %d files from rev %s\n') %
- (len(files), short(node)))
- else:
- ui.note(_('making snapshot of %d files from working directory\n') %
- (len(files)))
- wopener = util.opener(base)
- fns_and_mtime = []
- ctx = repo[node]
- for fn in files:
- wfn = util.pconvert(fn)
- if not wfn in ctx:
- # File doesn't exist; could be a bogus modify
- continue
- ui.note(' %s\n' % wfn)
- dest = os.path.join(base, wfn)
- fctx = ctx[wfn]
- data = repo.wwritedata(wfn, fctx.data())
- if 'l' in fctx.flags():
- wopener.symlink(data, wfn)
- else:
- wopener(wfn, 'w').write(data)
- if 'x' in fctx.flags():
- util.set_flags(dest, False, True)
- if node is None:
- fns_and_mtime.append((dest, repo.wjoin(fn), os.path.getmtime(dest)))
- return dirname, fns_and_mtime
-
-def dodiff(ui, repo, diffcmd, diffopts, pats, opts):
- '''Do the actuall diff:
-
- - copy to a temp structure if diffing 2 internal revisions
- - copy to a temp structure if diffing working revision with
- another one and more than 1 file is changed
- - just invoke the diff for a single file in the working dir
- '''
-
- revs = opts.get('rev')
- change = opts.get('change')
- args = ' '.join(diffopts)
- do3way = '$parent2' in args
-
- if revs and change:
- msg = _('cannot specify --rev and --change at the same time')
- raise util.Abort(msg)
- elif change:
- node2 = repo.lookup(change)
- node1a, node1b = repo.changelog.parents(node2)
- else:
- node1a, node2 = cmdutil.revpair(repo, revs)
- if not revs:
- node1b = repo.dirstate.parents()[1]
- else:
- node1b = nullid
-
- # Disable 3-way merge if there is only one parent
- if do3way:
- if node1b == nullid:
- do3way = False
-
- matcher = cmdutil.match(repo, pats, opts)
- mod_a, add_a, rem_a = map(set, repo.status(node1a, node2, matcher)[:3])
- if do3way:
- mod_b, add_b, rem_b = map(set, repo.status(node1b, node2, matcher)[:3])
- else:
- mod_b, add_b, rem_b = set(), set(), set()
- modadd = mod_a | add_a | mod_b | add_b
- common = modadd | rem_a | rem_b
- if not common:
- return 0
-
- tmproot = tempfile.mkdtemp(prefix='extdiff.')
- try:
- # Always make a copy of node1a (and node1b, if applicable)
- dir1a_files = mod_a | rem_a | ((mod_b | add_b) - add_a)
- dir1a = snapshot(ui, repo, dir1a_files, node1a, tmproot)[0]
- rev1a = '@%d' % repo[node1a].rev()
- if do3way:
- dir1b_files = mod_b | rem_b | ((mod_a | add_a) - add_b)
- dir1b = snapshot(ui, repo, dir1b_files, node1b, tmproot)[0]
- rev1b = '@%d' % repo[node1b].rev()
- else:
- dir1b = None
- rev1b = ''
-
- fns_and_mtime = []
-
- # If node2 in not the wc or there is >1 change, copy it
- dir2root = ''
- rev2 = ''
- if node2:
- dir2 = snapshot(ui, repo, modadd, node2, tmproot)[0]
- rev2 = '@%d' % repo[node2].rev()
- elif len(common) > 1:
- #we only actually need to get the files to copy back to
- #the working dir in this case (because the other cases
- #are: diffing 2 revisions or single file -- in which case
- #the file is already directly passed to the diff tool).
- dir2, fns_and_mtime = snapshot(ui, repo, modadd, None, tmproot)
- else:
- # This lets the diff tool open the changed file directly
- dir2 = ''
- dir2root = repo.root
-
- label1a = rev1a
- label1b = rev1b
- label2 = rev2
-
- # If only one change, diff the files instead of the directories
- # Handle bogus modifies correctly by checking if the files exist
- if len(common) == 1:
- common_file = util.localpath(common.pop())
- dir1a = os.path.join(dir1a, common_file)
- label1a = common_file + rev1a
- if not os.path.isfile(os.path.join(tmproot, dir1a)):
- dir1a = os.devnull
- if do3way:
- dir1b = os.path.join(dir1b, common_file)
- label1b = common_file + rev1b
- if not os.path.isfile(os.path.join(tmproot, dir1b)):
- dir1b = os.devnull
- dir2 = os.path.join(dir2root, dir2, common_file)
- label2 = common_file + rev2
-
- # Function to quote file/dir names in the argument string.
- # When not operating in 3-way mode, an empty string is
- # returned for parent2
- replace = dict(parent=dir1a, parent1=dir1a, parent2=dir1b,
- plabel1=label1a, plabel2=label1b,
- clabel=label2, child=dir2)
- def quote(match):
- key = match.group()[1:]
- if not do3way and key == 'parent2':
- return ''
- return util.shellquote(replace[key])
-
- # Match parent2 first, so 'parent1?' will match both parent1 and parent
- regex = '\$(parent2|parent1?|child|plabel1|plabel2|clabel)'
- if not do3way and not re.search(regex, args):
- args += ' $parent1 $child'
- args = re.sub(regex, quote, args)
- cmdline = util.shellquote(diffcmd) + ' ' + args
-
- ui.debug('running %r in %s\n' % (cmdline, tmproot))
- util.system(cmdline, cwd=tmproot)
-
- for copy_fn, working_fn, mtime in fns_and_mtime:
- if os.path.getmtime(copy_fn) != mtime:
- ui.debug('file changed while diffing. '
- 'Overwriting: %s (src: %s)\n' % (working_fn, copy_fn))
- util.copyfile(copy_fn, working_fn)
-
- return 1
- finally:
- ui.note(_('cleaning up temp directory\n'))
- shutil.rmtree(tmproot)
-
-def extdiff(ui, repo, *pats, **opts):
- '''use external program to diff repository (or selected files)
-
- Show differences between revisions for the specified files, using
- an external program. The default program used is diff, with
- default options "-Npru".
-
- To select a different program, use the -p/--program option. The
- program will be passed the names of two directories to compare. To
- pass additional options to the program, use -o/--option. These
- will be passed before the names of the directories to compare.
-
- When two revision arguments are given, then changes are shown
- between those revisions. If only one revision is specified then
- that revision is compared to the working directory, and, when no
- revisions are specified, the working directory files are compared
- to its parent.'''
- program = opts.get('program')
- option = opts.get('option')
- if not program:
- program = 'diff'
- option = option or ['-Npru']
- return dodiff(ui, repo, program, option, pats, opts)
-
-cmdtable = {
- "extdiff":
- (extdiff,
- [('p', 'program', '',
- _('comparison program to run'), _('CMD')),
- ('o', 'option', [],
- _('pass option to comparison program'), _('OPT')),
- ('r', 'rev', [],
- _('revision'), _('REV')),
- ('c', 'change', '',
- _('change made by revision'), _('REV')),
- ] + commands.walkopts,
- _('hg extdiff [OPT]... [FILE]...')),
- }
-
-def uisetup(ui):
- for cmd, path in ui.configitems('extdiff'):
- if cmd.startswith('cmd.'):
- cmd = cmd[4:]
- if not path:
- path = cmd
- diffopts = ui.config('extdiff', 'opts.' + cmd, '')
- diffopts = diffopts and [diffopts] or []
- elif cmd.startswith('opts.'):
- continue
- else:
- # command = path opts
- if path:
- diffopts = shlex.split(path)
- path = diffopts.pop(0)
- else:
- path, diffopts = cmd, []
- # look for diff arguments in [diff-tools] then [merge-tools]
- if diffopts == []:
- args = ui.config('diff-tools', cmd+'.diffargs') or \
- ui.config('merge-tools', cmd+'.diffargs')
- if args:
- diffopts = shlex.split(args)
- def save(cmd, path, diffopts):
- '''use closure to save diff command to use'''
- def mydiff(ui, repo, *pats, **opts):
- return dodiff(ui, repo, path, diffopts + opts['option'],
- pats, opts)
- doc = _('''\
-use %(path)s to diff repository (or selected files)
-
- Show differences between revisions for the specified files, using
- the %(path)s program.
-
- When two revision arguments are given, then changes are shown
- between those revisions. If only one revision is specified then
- that revision is compared to the working directory, and, when no
- revisions are specified, the working directory files are compared
- to its parent.\
-''') % dict(path=util.uirepr(path))
-
- # We must translate the docstring right away since it is
- # used as a format string. The string will unfortunately
- # be translated again in commands.helpcmd and this will
- # fail when the docstring contains non-ASCII characters.
- # Decoding the string to a Unicode string here (using the
- # right encoding) prevents that.
- mydiff.__doc__ = doc.decode(encoding.encoding)
- return mydiff
- cmdtable[cmd] = (save(cmd, path, diffopts),
- cmdtable['extdiff'][1][1:],
- _('hg %s [OPTION]... [FILE]...') % cmd)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.pyo
deleted file mode 100644
index 008d690..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/extdiff.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.py
deleted file mode 100644
index b8e765f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# fetch.py - pull and merge remote changes
-#
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''pull, update and merge in one command'''
-
-from mercurial.i18n import _
-from mercurial.node import nullid, short
-from mercurial import commands, cmdutil, hg, util, url, error
-from mercurial.lock import release
-
-def fetch(ui, repo, source='default', **opts):
- '''pull changes from a remote repository, merge new changes if needed.
-
- This finds all changes from the repository at the specified path
- or URL and adds them to the local repository.
-
- If the pulled changes add a new branch head, the head is
- automatically merged, and the result of the merge is committed.
- Otherwise, the working directory is updated to include the new
- changes.
-
- When a merge occurs, the newly pulled changes are assumed to be
- "authoritative". The head of the new changes is used as the first
- parent, with local changes as the second. To switch the merge
- order, use --switch-parent.
-
- See :hg:`help dates` for a list of formats valid for -d/--date.
-
- Returns 0 on success.
- '''
-
- date = opts.get('date')
- if date:
- opts['date'] = util.parsedate(date)
-
- parent, p2 = repo.dirstate.parents()
- branch = repo.dirstate.branch()
- branchnode = repo.branchtags().get(branch)
- if parent != branchnode:
- raise util.Abort(_('working dir not at branch tip '
- '(use "hg update" to check out branch tip)'))
-
- if p2 != nullid:
- raise util.Abort(_('outstanding uncommitted merge'))
-
- wlock = lock = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- mod, add, rem, del_ = repo.status()[:4]
-
- if mod or add or rem:
- raise util.Abort(_('outstanding uncommitted changes'))
- if del_:
- raise util.Abort(_('working directory is missing some files'))
- bheads = repo.branchheads(branch)
- bheads = [head for head in bheads if len(repo[head].children()) == 0]
- if len(bheads) > 1:
- raise util.Abort(_('multiple heads in this branch '
- '(use "hg heads ." and "hg merge" to merge)'))
-
- other = hg.repository(hg.remoteui(repo, opts),
- ui.expandpath(source))
- ui.status(_('pulling from %s\n') %
- url.hidepassword(ui.expandpath(source)))
- revs = None
- if opts['rev']:
- try:
- revs = [other.lookup(rev) for rev in opts['rev']]
- except error.CapabilityError:
- err = _("Other repository doesn't support revision lookup, "
- "so a rev cannot be specified.")
- raise util.Abort(err)
-
- # Are there any changes at all?
- modheads = repo.pull(other, heads=revs)
- if modheads == 0:
- return 0
-
- # Is this a simple fast-forward along the current branch?
- newheads = repo.branchheads(branch)
- newchildren = repo.changelog.nodesbetween([parent], newheads)[2]
- if len(newheads) == 1:
- if newchildren[0] != parent:
- return hg.clean(repo, newchildren[0])
- else:
- return 0
-
- # Are there more than one additional branch heads?
- newchildren = [n for n in newchildren if n != parent]
- newparent = parent
- if newchildren:
- newparent = newchildren[0]
- hg.clean(repo, newparent)
- newheads = [n for n in newheads if n != newparent]
- if len(newheads) > 1:
- ui.status(_('not merging with %d other new branch heads '
- '(use "hg heads ." and "hg merge" to merge them)\n') %
- (len(newheads) - 1))
- return 1
-
- # Otherwise, let's merge.
- err = False
- if newheads:
- # By default, we consider the repository we're pulling
- # *from* as authoritative, so we merge our changes into
- # theirs.
- if opts['switch_parent']:
- firstparent, secondparent = newparent, newheads[0]
- else:
- firstparent, secondparent = newheads[0], newparent
- ui.status(_('updating to %d:%s\n') %
- (repo.changelog.rev(firstparent),
- short(firstparent)))
- hg.clean(repo, firstparent)
- ui.status(_('merging with %d:%s\n') %
- (repo.changelog.rev(secondparent), short(secondparent)))
- err = hg.merge(repo, secondparent, remind=False)
-
- if not err:
- # we don't translate commit messages
- message = (cmdutil.logmessage(opts) or
- ('Automated merge with %s' %
- url.removeauth(other.url())))
- editor = cmdutil.commiteditor
- if opts.get('force_editor') or opts.get('edit'):
- editor = cmdutil.commitforceeditor
- n = repo.commit(message, opts['user'], opts['date'], editor=editor)
- ui.status(_('new changeset %d:%s merges remote changes '
- 'with local\n') % (repo.changelog.rev(n),
- short(n)))
-
- return err
-
- finally:
- release(lock, wlock)
-
-cmdtable = {
- 'fetch':
- (fetch,
- [('r', 'rev', [],
- _('a specific revision you would like to pull'), _('REV')),
- ('e', 'edit', None, _('edit commit message')),
- ('', 'force-editor', None, _('edit commit message (DEPRECATED)')),
- ('', 'switch-parent', None, _('switch parents when merging')),
- ] + commands.commitopts + commands.commitopts2 + commands.remoteopts,
- _('hg fetch [SOURCE]')),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.pyo
deleted file mode 100644
index c8529ef..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/fetch.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.py
deleted file mode 100644
index b13ec1e..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# Copyright 2005, 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''commands to sign and verify changesets'''
-
-import os, tempfile, binascii
-from mercurial import util, commands, match
-from mercurial import node as hgnode
-from mercurial.i18n import _
-
-class gpg(object):
- def __init__(self, path, key=None):
- self.path = path
- self.key = (key and " --local-user \"%s\"" % key) or ""
-
- def sign(self, data):
- gpgcmd = "%s --sign --detach-sign%s" % (self.path, self.key)
- return util.filter(data, gpgcmd)
-
- def verify(self, data, sig):
- """ returns of the good and bad signatures"""
- sigfile = datafile = None
- try:
- # create temporary files
- fd, sigfile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".sig")
- fp = os.fdopen(fd, 'wb')
- fp.write(sig)
- fp.close()
- fd, datafile = tempfile.mkstemp(prefix="hg-gpg-", suffix=".txt")
- fp = os.fdopen(fd, 'wb')
- fp.write(data)
- fp.close()
- gpgcmd = ("%s --logger-fd 1 --status-fd 1 --verify "
- "\"%s\" \"%s\"" % (self.path, sigfile, datafile))
- ret = util.filter("", gpgcmd)
- finally:
- for f in (sigfile, datafile):
- try:
- if f:
- os.unlink(f)
- except:
- pass
- keys = []
- key, fingerprint = None, None
- err = ""
- for l in ret.splitlines():
- # see DETAILS in the gnupg documentation
- # filter the logger output
- if not l.startswith("[GNUPG:]"):
- continue
- l = l[9:]
- if l.startswith("ERRSIG"):
- err = _("error while verifying signature")
- break
- elif l.startswith("VALIDSIG"):
- # fingerprint of the primary key
- fingerprint = l.split()[10]
- elif (l.startswith("GOODSIG") or
- l.startswith("EXPSIG") or
- l.startswith("EXPKEYSIG") or
- l.startswith("BADSIG")):
- if key is not None:
- keys.append(key + [fingerprint])
- key = l.split(" ", 2)
- fingerprint = None
- if err:
- return err, []
- if key is not None:
- keys.append(key + [fingerprint])
- return err, keys
-
-def newgpg(ui, **opts):
- """create a new gpg instance"""
- gpgpath = ui.config("gpg", "cmd", "gpg")
- gpgkey = opts.get('key')
- if not gpgkey:
- gpgkey = ui.config("gpg", "key", None)
- return gpg(gpgpath, gpgkey)
-
-def sigwalk(repo):
- """
- walk over every sigs, yields a couple
- ((node, version, sig), (filename, linenumber))
- """
- def parsefile(fileiter, context):
- ln = 1
- for l in fileiter:
- if not l:
- continue
- yield (l.split(" ", 2), (context, ln))
- ln += 1
-
- # read the heads
- fl = repo.file(".hgsigs")
- for r in reversed(fl.heads()):
- fn = ".hgsigs|%s" % hgnode.short(r)
- for item in parsefile(fl.read(r).splitlines(), fn):
- yield item
- try:
- # read local signatures
- fn = "localsigs"
- for item in parsefile(repo.opener(fn), fn):
- yield item
- except IOError:
- pass
-
-def getkeys(ui, repo, mygpg, sigdata, context):
- """get the keys who signed a data"""
- fn, ln = context
- node, version, sig = sigdata
- prefix = "%s:%d" % (fn, ln)
- node = hgnode.bin(node)
-
- data = node2txt(repo, node, version)
- sig = binascii.a2b_base64(sig)
- err, keys = mygpg.verify(data, sig)
- if err:
- ui.warn("%s:%d %s\n" % (fn, ln , err))
- return None
-
- validkeys = []
- # warn for expired key and/or sigs
- for key in keys:
- if key[0] == "BADSIG":
- ui.write(_("%s Bad signature from \"%s\"\n") % (prefix, key[2]))
- continue
- if key[0] == "EXPSIG":
- ui.write(_("%s Note: Signature has expired"
- " (signed by: \"%s\")\n") % (prefix, key[2]))
- elif key[0] == "EXPKEYSIG":
- ui.write(_("%s Note: This key has expired"
- " (signed by: \"%s\")\n") % (prefix, key[2]))
- validkeys.append((key[1], key[2], key[3]))
- return validkeys
-
-def sigs(ui, repo):
- """list signed changesets"""
- mygpg = newgpg(ui)
- revs = {}
-
- for data, context in sigwalk(repo):
- node, version, sig = data
- fn, ln = context
- try:
- n = repo.lookup(node)
- except KeyError:
- ui.warn(_("%s:%d node does not exist\n") % (fn, ln))
- continue
- r = repo.changelog.rev(n)
- keys = getkeys(ui, repo, mygpg, data, context)
- if not keys:
- continue
- revs.setdefault(r, [])
- revs[r].extend(keys)
- for rev in sorted(revs, reverse=True):
- for k in revs[rev]:
- r = "%5d:%s" % (rev, hgnode.hex(repo.changelog.node(rev)))
- ui.write("%-30s %s\n" % (keystr(ui, k), r))
-
-def check(ui, repo, rev):
- """verify all the signatures there may be for a particular revision"""
- mygpg = newgpg(ui)
- rev = repo.lookup(rev)
- hexrev = hgnode.hex(rev)
- keys = []
-
- for data, context in sigwalk(repo):
- node, version, sig = data
- if node == hexrev:
- k = getkeys(ui, repo, mygpg, data, context)
- if k:
- keys.extend(k)
-
- if not keys:
- ui.write(_("No valid signature for %s\n") % hgnode.short(rev))
- return
-
- # print summary
- ui.write("%s is signed by:\n" % hgnode.short(rev))
- for key in keys:
- ui.write(" %s\n" % keystr(ui, key))
-
-def keystr(ui, key):
- """associate a string to a key (username, comment)"""
- keyid, user, fingerprint = key
- comment = ui.config("gpg", fingerprint, None)
- if comment:
- return "%s (%s)" % (user, comment)
- else:
- return user
-
-def sign(ui, repo, *revs, **opts):
- """add a signature for the current or given revision
-
- If no revision is given, the parent of the working directory is used,
- or tip if no revision is checked out.
-
- See :hg:`help dates` for a list of formats valid for -d/--date.
- """
-
- mygpg = newgpg(ui, **opts)
- sigver = "0"
- sigmessage = ""
-
- date = opts.get('date')
- if date:
- opts['date'] = util.parsedate(date)
-
- if revs:
- nodes = [repo.lookup(n) for n in revs]
- else:
- nodes = [node for node in repo.dirstate.parents()
- if node != hgnode.nullid]
- if len(nodes) > 1:
- raise util.Abort(_('uncommitted merge - please provide a '
- 'specific revision'))
- if not nodes:
- nodes = [repo.changelog.tip()]
-
- for n in nodes:
- hexnode = hgnode.hex(n)
- ui.write(_("Signing %d:%s\n") % (repo.changelog.rev(n),
- hgnode.short(n)))
- # build data
- data = node2txt(repo, n, sigver)
- sig = mygpg.sign(data)
- if not sig:
- raise util.Abort(_("error while signing"))
- sig = binascii.b2a_base64(sig)
- sig = sig.replace("\n", "")
- sigmessage += "%s %s %s\n" % (hexnode, sigver, sig)
-
- # write it
- if opts['local']:
- repo.opener("localsigs", "ab").write(sigmessage)
- return
-
- msigs = match.exact(repo.root, '', ['.hgsigs'])
- s = repo.status(match=msigs, unknown=True, ignored=True)[:6]
- if util.any(s) and not opts["force"]:
- raise util.Abort(_("working copy of .hgsigs is changed "
- "(please commit .hgsigs manually "
- "or use --force)"))
-
- repo.wfile(".hgsigs", "ab").write(sigmessage)
-
- if '.hgsigs' not in repo.dirstate:
- repo[None].add([".hgsigs"])
-
- if opts["no_commit"]:
- return
-
- message = opts['message']
- if not message:
- # we don't translate commit messages
- message = "\n".join(["Added signature for changeset %s"
- % hgnode.short(n)
- for n in nodes])
- try:
- repo.commit(message, opts['user'], opts['date'], match=msigs)
- except ValueError, inst:
- raise util.Abort(str(inst))
-
-def node2txt(repo, node, ver):
- """map a manifest into some text"""
- if ver == "0":
- return "%s\n" % hgnode.hex(node)
- else:
- raise util.Abort(_("unknown signature version"))
-
-cmdtable = {
- "sign":
- (sign,
- [('l', 'local', None, _('make the signature local')),
- ('f', 'force', None, _('sign even if the sigfile is modified')),
- ('', 'no-commit', None, _('do not commit the sigfile after signing')),
- ('k', 'key', '',
- _('the key id to sign with'), _('ID')),
- ('m', 'message', '',
- _('commit message'), _('TEXT')),
- ] + commands.commitopts2,
- _('hg sign [OPTION]... [REVISION]...')),
- "sigcheck": (check, [], _('hg sigcheck REVISION')),
- "sigs": (sigs, [], _('hg sigs')),
-}
-
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.pyo
deleted file mode 100644
index 3d5d415..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/gpg.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.py
deleted file mode 100644
index a8eb805..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.py
+++ /dev/null
@@ -1,337 +0,0 @@
-# ASCII graph log extension for Mercurial
-#
-# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to view revision graphs from a shell
-
-This extension adds a --graph option to the incoming, outgoing and log
-commands. When this options is given, an ASCII representation of the
-revision graph is also shown.
-'''
-
-import os
-from mercurial.cmdutil import revrange, show_changeset
-from mercurial.commands import templateopts
-from mercurial.i18n import _
-from mercurial.node import nullrev
-from mercurial import cmdutil, commands, extensions
-from mercurial import hg, util, graphmod
-
-ASCIIDATA = 'ASC'
-
-def asciiedges(seen, rev, parents):
- """adds edge info to changelog DAG walk suitable for ascii()"""
- if rev not in seen:
- seen.append(rev)
- nodeidx = seen.index(rev)
-
- knownparents = []
- newparents = []
- for parent in parents:
- if parent in seen:
- knownparents.append(parent)
- else:
- newparents.append(parent)
-
- ncols = len(seen)
- seen[nodeidx:nodeidx + 1] = newparents
- edges = [(nodeidx, seen.index(p)) for p in knownparents]
-
- if len(newparents) > 0:
- edges.append((nodeidx, nodeidx))
- if len(newparents) > 1:
- edges.append((nodeidx, nodeidx + 1))
-
- nmorecols = len(seen) - ncols
- return nodeidx, edges, ncols, nmorecols
-
-def fix_long_right_edges(edges):
- for (i, (start, end)) in enumerate(edges):
- if end > start:
- edges[i] = (start, end + 1)
-
-def get_nodeline_edges_tail(
- node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
- if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
- # Still going in the same non-vertical direction.
- if n_columns_diff == -1:
- start = max(node_index + 1, p_node_index)
- tail = ["|", " "] * (start - node_index - 1)
- tail.extend(["/", " "] * (n_columns - start))
- return tail
- else:
- return ["\\", " "] * (n_columns - node_index - 1)
- else:
- return ["|", " "] * (n_columns - node_index - 1)
-
-def draw_edges(edges, nodeline, interline):
- for (start, end) in edges:
- if start == end + 1:
- interline[2 * end + 1] = "/"
- elif start == end - 1:
- interline[2 * start + 1] = "\\"
- elif start == end:
- interline[2 * start] = "|"
- else:
- nodeline[2 * end] = "+"
- if start > end:
- (start, end) = (end, start)
- for i in range(2 * start + 1, 2 * end):
- if nodeline[i] != "+":
- nodeline[i] = "-"
-
-def get_padding_line(ni, n_columns, edges):
- line = []
- line.extend(["|", " "] * ni)
- if (ni, ni - 1) in edges or (ni, ni) in edges:
- # (ni, ni - 1) (ni, ni)
- # | | | | | | | |
- # +---o | | o---+
- # | | c | | c | |
- # | |/ / | |/ /
- # | | | | | |
- c = "|"
- else:
- c = " "
- line.extend([c, " "])
- line.extend(["|", " "] * (n_columns - ni - 1))
- return line
-
-def asciistate():
- """returns the initial value for the "state" argument to ascii()"""
- return [0, 0]
-
-def ascii(ui, state, type, char, text, coldata):
- """prints an ASCII graph of the DAG
-
- takes the following arguments (one call per node in the graph):
-
- - ui to write to
- - Somewhere to keep the needed state in (init to asciistate())
- - Column of the current node in the set of ongoing edges.
- - Type indicator of node data == ASCIIDATA.
- - Payload: (char, lines):
- - Character to use as node's symbol.
- - List of lines to display as the node's text.
- - Edges; a list of (col, next_col) indicating the edges between
- the current node and its parents.
- - Number of columns (ongoing edges) in the current revision.
- - The difference between the number of columns (ongoing edges)
- in the next revision and the number of columns (ongoing edges)
- in the current revision. That is: -1 means one column removed;
- 0 means no columns added or removed; 1 means one column added.
- """
-
- idx, edges, ncols, coldiff = coldata
- assert -2 < coldiff < 2
- if coldiff == -1:
- # Transform
- #
- # | | | | | |
- # o | | into o---+
- # |X / |/ /
- # | | | |
- fix_long_right_edges(edges)
-
- # add_padding_line says whether to rewrite
- #
- # | | | | | | | |
- # | o---+ into | o---+
- # | / / | | | # <--- padding line
- # o | | | / /
- # o | |
- add_padding_line = (len(text) > 2 and coldiff == -1 and
- [x for (x, y) in edges if x + 1 < y])
-
- # fix_nodeline_tail says whether to rewrite
- #
- # | | o | | | | o | |
- # | | |/ / | | |/ /
- # | o | | into | o / / # <--- fixed nodeline tail
- # | |/ / | |/ /
- # o | | o | |
- fix_nodeline_tail = len(text) <= 2 and not add_padding_line
-
- # nodeline is the line containing the node character (typically o)
- nodeline = ["|", " "] * idx
- nodeline.extend([char, " "])
-
- nodeline.extend(
- get_nodeline_edges_tail(idx, state[1], ncols, coldiff,
- state[0], fix_nodeline_tail))
-
- # shift_interline is the line containing the non-vertical
- # edges between this entry and the next
- shift_interline = ["|", " "] * idx
- if coldiff == -1:
- n_spaces = 1
- edge_ch = "/"
- elif coldiff == 0:
- n_spaces = 2
- edge_ch = "|"
- else:
- n_spaces = 3
- edge_ch = "\\"
- shift_interline.extend(n_spaces * [" "])
- shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
-
- # draw edges from the current node to its parents
- draw_edges(edges, nodeline, shift_interline)
-
- # lines is the list of all graph lines to print
- lines = [nodeline]
- if add_padding_line:
- lines.append(get_padding_line(idx, ncols, edges))
- lines.append(shift_interline)
-
- # make sure that there are as many graph lines as there are
- # log strings
- while len(text) < len(lines):
- text.append("")
- if len(lines) < len(text):
- extra_interline = ["|", " "] * (ncols + coldiff)
- while len(lines) < len(text):
- lines.append(extra_interline)
-
- # print lines
- indentation_level = max(ncols, ncols + coldiff)
- for (line, logstr) in zip(lines, text):
- ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
- ui.write(ln.rstrip() + '\n')
-
- # ... and start over
- state[0] = coldiff
- state[1] = idx
-
-def get_revs(repo, rev_opt):
- if rev_opt:
- revs = revrange(repo, rev_opt)
- if len(revs) == 0:
- return (nullrev, nullrev)
- return (max(revs), min(revs))
- else:
- return (len(repo) - 1, 0)
-
-def check_unsupported_flags(opts):
- for op in ["follow", "follow_first", "date", "copies", "keyword", "remove",
- "only_merges", "user", "branch", "only_branch", "prune",
- "newest_first", "no_merges", "include", "exclude"]:
- if op in opts and opts[op]:
- raise util.Abort(_("--graph option is incompatible with --%s")
- % op.replace("_", "-"))
-
-def generate(ui, dag, displayer, showparents, edgefn):
- seen, state = [], asciistate()
- for rev, type, ctx, parents in dag:
- char = ctx.node() in showparents and '@' or 'o'
- displayer.show(ctx)
- lines = displayer.hunk.pop(rev).split('\n')[:-1]
- displayer.flush(rev)
- ascii(ui, state, type, char, lines, edgefn(seen, rev, parents))
- displayer.close()
-
-def graphlog(ui, repo, path=None, **opts):
- """show revision history alongside an ASCII revision graph
-
- Print a revision history alongside a revision graph drawn with
- ASCII characters.
-
- Nodes printed as an @ character are parents of the working
- directory.
- """
-
- check_unsupported_flags(opts)
- limit = cmdutil.loglimit(opts)
- start, stop = get_revs(repo, opts["rev"])
- if start == nullrev:
- return
-
- if path:
- path = util.canonpath(repo.root, os.getcwd(), path)
- if path: # could be reset in canonpath
- revdag = graphmod.filerevs(repo, path, start, stop, limit)
- else:
- if limit is not None:
- stop = max(stop, start - limit + 1)
- revdag = graphmod.revisions(repo, start, stop)
-
- displayer = show_changeset(ui, repo, opts, buffered=True)
- showparents = [ctx.node() for ctx in repo[None].parents()]
- generate(ui, revdag, displayer, showparents, asciiedges)
-
-def graphrevs(repo, nodes, opts):
- limit = cmdutil.loglimit(opts)
- nodes.reverse()
- if limit is not None:
- nodes = nodes[:limit]
- return graphmod.nodes(repo, nodes)
-
-def goutgoing(ui, repo, dest=None, **opts):
- """show the outgoing changesets alongside an ASCII revision graph
-
- Print the outgoing changesets alongside a revision graph drawn with
- ASCII characters.
-
- Nodes printed as an @ character are parents of the working
- directory.
- """
-
- check_unsupported_flags(opts)
- o = hg._outgoing(ui, repo, dest, opts)
- if o is None:
- return
-
- revdag = graphrevs(repo, o, opts)
- displayer = show_changeset(ui, repo, opts, buffered=True)
- showparents = [ctx.node() for ctx in repo[None].parents()]
- generate(ui, revdag, displayer, showparents, asciiedges)
-
-def gincoming(ui, repo, source="default", **opts):
- """show the incoming changesets alongside an ASCII revision graph
-
- Print the incoming changesets alongside a revision graph drawn with
- ASCII characters.
-
- Nodes printed as an @ character are parents of the working
- directory.
- """
- def subreporecurse():
- return 1
-
- check_unsupported_flags(opts)
- def display(other, chlist, displayer):
- revdag = graphrevs(other, chlist, opts)
- showparents = [ctx.node() for ctx in repo[None].parents()]
- generate(ui, revdag, displayer, showparents, asciiedges)
-
- hg._incoming(display, subreporecurse, ui, repo, source, opts, buffered=True)
-
-def uisetup(ui):
- '''Initialize the extension.'''
- _wrapcmd(ui, 'log', commands.table, graphlog)
- _wrapcmd(ui, 'incoming', commands.table, gincoming)
- _wrapcmd(ui, 'outgoing', commands.table, goutgoing)
-
-def _wrapcmd(ui, cmd, table, wrapfn):
- '''wrap the command'''
- def graph(orig, *args, **kwargs):
- if kwargs['graph']:
- return wrapfn(*args, **kwargs)
- return orig(*args, **kwargs)
- entry = extensions.wrapcommand(table, cmd, graph)
- entry[1].append(('G', 'graph', None, _("show the revision DAG")))
-
-cmdtable = {
- "glog":
- (graphlog,
- [('l', 'limit', '',
- _('limit number of changes displayed'), _('NUM')),
- ('p', 'patch', False, _('show patch')),
- ('r', 'rev', [],
- _('show the specified revision or range'), _('REV')),
- ] + templateopts,
- _('hg glog [OPTION]... [FILE]')),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.pyo
deleted file mode 100644
index 2edc5f3..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/graphlog.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.py
deleted file mode 100644
index 4e72680..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright (C) 2007-8 Brendan Cully <brendan@kublai.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-"""hooks for integrating with the CIA.vc notification service
-
-This is meant to be run as a changegroup or incoming hook. To
-configure it, set the following options in your hgrc::
-
- [cia]
- # your registered CIA user name
- user = foo
- # the name of the project in CIA
- project = foo
- # the module (subproject) (optional)
- #module = foo
- # Append a diffstat to the log message (optional)
- #diffstat = False
- # Template to use for log messages (optional)
- #template = {desc}\\n{baseurl}/rev/{node}-- {diffstat}
- # Style to use (optional)
- #style = foo
- # The URL of the CIA notification service (optional)
- # You can use mailto: URLs to send by email, eg
- # mailto:cia@cia.vc
- # Make sure to set email.from if you do this.
- #url = http://cia.vc/
- # print message instead of sending it (optional)
- #test = False
-
- [hooks]
- # one of these:
- changegroup.cia = python:hgcia.hook
- #incoming.cia = python:hgcia.hook
-
- [web]
- # If you want hyperlinks (optional)
- baseurl = http://server/path/to/repo
-"""
-
-from mercurial.i18n import _
-from mercurial.node import bin, short
-from mercurial import cmdutil, patch, templater, util, mail
-import email.Parser
-
-import xmlrpclib
-from xml.sax import saxutils
-
-socket_timeout = 30 # seconds
-try:
- # set a timeout for the socket so you don't have to wait so looooong
- # when cia.vc is having problems. requires python >= 2.3:
- import socket
- socket.setdefaulttimeout(socket_timeout)
-except:
- pass
-
-HGCIA_VERSION = '0.1'
-HGCIA_URL = 'http://hg.kublai.com/mercurial/hgcia'
-
-
-class ciamsg(object):
- """ A CIA message """
- def __init__(self, cia, ctx):
- self.cia = cia
- self.ctx = ctx
- self.url = self.cia.url
-
- def fileelem(self, path, uri, action):
- if uri:
- uri = ' uri=%s' % saxutils.quoteattr(uri)
- return '<file%s action=%s>%s</file>' % (
- uri, saxutils.quoteattr(action), saxutils.escape(path))
-
- def fileelems(self):
- n = self.ctx.node()
- f = self.cia.repo.status(self.ctx.parents()[0].node(), n)
- url = self.url or ''
- elems = []
- for path in f[0]:
- uri = '%s/diff/%s/%s' % (url, short(n), path)
- elems.append(self.fileelem(path, url and uri, 'modify'))
- for path in f[1]:
- # TODO: copy/rename ?
- uri = '%s/file/%s/%s' % (url, short(n), path)
- elems.append(self.fileelem(path, url and uri, 'add'))
- for path in f[2]:
- elems.append(self.fileelem(path, '', 'remove'))
-
- return '\n'.join(elems)
-
- def sourceelem(self, project, module=None, branch=None):
- msg = ['<source>', '<project>%s</project>' % saxutils.escape(project)]
- if module:
- msg.append('<module>%s</module>' % saxutils.escape(module))
- if branch:
- msg.append('<branch>%s</branch>' % saxutils.escape(branch))
- msg.append('</source>')
-
- return '\n'.join(msg)
-
- def diffstat(self):
- class patchbuf(object):
- def __init__(self):
- self.lines = []
- # diffstat is stupid
- self.name = 'cia'
- def write(self, data):
- self.lines.append(data)
- def close(self):
- pass
-
- n = self.ctx.node()
- pbuf = patchbuf()
- cmdutil.export(self.cia.repo, [n], fp=pbuf)
- return patch.diffstat(pbuf.lines) or ''
-
- def logmsg(self):
- diffstat = self.cia.diffstat and self.diffstat() or ''
- self.cia.ui.pushbuffer()
- self.cia.templater.show(self.ctx, changes=self.ctx.changeset(),
- url=self.cia.url, diffstat=diffstat)
- return self.cia.ui.popbuffer()
-
- def xml(self):
- n = short(self.ctx.node())
- src = self.sourceelem(self.cia.project, module=self.cia.module,
- branch=self.ctx.branch())
- # unix timestamp
- dt = self.ctx.date()
- timestamp = dt[0]
-
- author = saxutils.escape(self.ctx.user())
- rev = '%d:%s' % (self.ctx.rev(), n)
- log = saxutils.escape(self.logmsg())
-
- url = self.url and '<url>%s/rev/%s</url>' % (saxutils.escape(self.url),
- n) or ''
-
- msg = """
-<message>
- <generator>
- <name>Mercurial (hgcia)</name>
- <version>%s</version>
- <url>%s</url>
- <user>%s</user>
- </generator>
- %s
- <body>
- <commit>
- <author>%s</author>
- <version>%s</version>
- <log>%s</log>
- %s
- <files>%s</files>
- </commit>
- </body>
- <timestamp>%d</timestamp>
-</message>
-""" % \
- (HGCIA_VERSION, saxutils.escape(HGCIA_URL),
- saxutils.escape(self.cia.user), src, author, rev, log, url,
- self.fileelems(), timestamp)
-
- return msg
-
-
-class hgcia(object):
- """ CIA notification class """
-
- deftemplate = '{desc}'
- dstemplate = '{desc}\n-- \n{diffstat}'
-
- def __init__(self, ui, repo):
- self.ui = ui
- self.repo = repo
-
- self.ciaurl = self.ui.config('cia', 'url', 'http://cia.vc')
- self.user = self.ui.config('cia', 'user')
- self.project = self.ui.config('cia', 'project')
- self.module = self.ui.config('cia', 'module')
- self.diffstat = self.ui.configbool('cia', 'diffstat')
- self.emailfrom = self.ui.config('email', 'from')
- self.dryrun = self.ui.configbool('cia', 'test')
- self.url = self.ui.config('web', 'baseurl')
-
- style = self.ui.config('cia', 'style')
- template = self.ui.config('cia', 'template')
- if not template:
- template = self.diffstat and self.dstemplate or self.deftemplate
- template = templater.parsestring(template, quoted=False)
- t = cmdutil.changeset_templater(self.ui, self.repo, False, None,
- style, False)
- t.use_template(template)
- self.templater = t
-
- def sendrpc(self, msg):
- srv = xmlrpclib.Server(self.ciaurl)
- res = srv.hub.deliver(msg)
- if res is not True:
- raise util.Abort(_('%s returned an error: %s') %
- (self.ciaurl, res))
-
- def sendemail(self, address, data):
- p = email.Parser.Parser()
- msg = p.parsestr(data)
- msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
- msg['To'] = address
- msg['From'] = self.emailfrom
- msg['Subject'] = 'DeliverXML'
- msg['Content-type'] = 'text/xml'
- msgtext = msg.as_string()
-
- self.ui.status(_('hgcia: sending update to %s\n') % address)
- mail.sendmail(self.ui, util.email(self.emailfrom),
- [address], msgtext)
-
-
-def hook(ui, repo, hooktype, node=None, url=None, **kwargs):
- """ send CIA notification """
- def sendmsg(cia, ctx):
- msg = ciamsg(cia, ctx).xml()
- if cia.dryrun:
- ui.write(msg)
- elif cia.ciaurl.startswith('mailto:'):
- if not cia.emailfrom:
- raise util.Abort(_('email.from must be defined when '
- 'sending by email'))
- cia.sendemail(cia.ciaurl[7:], msg)
- else:
- cia.sendrpc(msg)
-
- n = bin(node)
- cia = hgcia(ui, repo)
- if not cia.user:
- ui.debug('cia: no user specified')
- return
- if not cia.project:
- ui.debug('cia: no project specified')
- return
- if hooktype == 'changegroup':
- start = repo.changelog.rev(n)
- end = len(repo.changelog)
- for rev in xrange(start, end):
- n = repo.changelog.node(rev)
- ctx = repo.changectx(n)
- sendmsg(cia, ctx)
- else:
- ctx = repo.changectx(n)
- sendmsg(cia, ctx)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.pyo
deleted file mode 100644
index 2c5a2ee..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgcia.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.py
deleted file mode 100644
index e8aae47..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# Minimal support for git commands on an hg repository
-#
-# Copyright 2005, 2006 Chris Mason <mason@suse.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''browse the repository in a graphical way
-
-The hgk extension allows browsing the history of a repository in a
-graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not
-distributed with Mercurial.)
-
-hgk consists of two parts: a Tcl script that does the displaying and
-querying of information, and an extension to Mercurial named hgk.py,
-which provides hooks for hgk to get information. hgk can be found in
-the contrib directory, and the extension is shipped in the hgext
-repository, and needs to be enabled.
-
-The :hg:`view` command will launch the hgk Tcl script. For this command
-to work, hgk must be in your search path. Alternately, you can specify
-the path to hgk in your configuration file::
-
- [hgk]
- path=/location/of/hgk
-
-hgk can make use of the extdiff extension to visualize revisions.
-Assuming you had already configured extdiff vdiff command, just add::
-
- [hgk]
- vdiff=vdiff
-
-Revisions context menu will now display additional entries to fire
-vdiff on hovered and selected revisions.
-'''
-
-import os
-from mercurial import commands, util, patch, revlog, cmdutil
-from mercurial.node import nullid, nullrev, short
-from mercurial.i18n import _
-
-def difftree(ui, repo, node1=None, node2=None, *files, **opts):
- """diff trees from two commits"""
- def __difftree(repo, node1, node2, files=[]):
- assert node2 is not None
- mmap = repo[node1].manifest()
- mmap2 = repo[node2].manifest()
- m = cmdutil.match(repo, files)
- modified, added, removed = repo.status(node1, node2, m)[:3]
- empty = short(nullid)
-
- for f in modified:
- # TODO get file permissions
- ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
- (short(mmap[f]), short(mmap2[f]), f, f))
- for f in added:
- ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
- (empty, short(mmap2[f]), f, f))
- for f in removed:
- ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
- (short(mmap[f]), empty, f, f))
- ##
-
- while True:
- if opts['stdin']:
- try:
- line = raw_input().split(' ')
- node1 = line[0]
- if len(line) > 1:
- node2 = line[1]
- else:
- node2 = None
- except EOFError:
- break
- node1 = repo.lookup(node1)
- if node2:
- node2 = repo.lookup(node2)
- else:
- node2 = node1
- node1 = repo.changelog.parents(node1)[0]
- if opts['patch']:
- if opts['pretty']:
- catcommit(ui, repo, node2, "")
- m = cmdutil.match(repo, files)
- chunks = patch.diff(repo, node1, node2, match=m,
- opts=patch.diffopts(ui, {'git': True}))
- for chunk in chunks:
- ui.write(chunk)
- else:
- __difftree(repo, node1, node2, files=files)
- if not opts['stdin']:
- break
-
-def catcommit(ui, repo, n, prefix, ctx=None):
- nlprefix = '\n' + prefix
- if ctx is None:
- ctx = repo[n]
- ui.write("tree %s\n" % short(ctx.changeset()[0])) # use ctx.node() instead ??
- for p in ctx.parents():
- ui.write("parent %s\n" % p)
-
- date = ctx.date()
- description = ctx.description().replace("\0", "")
- lines = description.splitlines()
- if lines and lines[-1].startswith('committer:'):
- committer = lines[-1].split(': ')[1].rstrip()
- else:
- committer = ctx.user()
-
- ui.write("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1]))
- ui.write("committer %s %s %s\n" % (committer, int(date[0]), date[1]))
- ui.write("revision %d\n" % ctx.rev())
- ui.write("branch %s\n\n" % ctx.branch())
-
- if prefix != "":
- ui.write("%s%s\n" % (prefix, description.replace('\n', nlprefix).strip()))
- else:
- ui.write(description + "\n")
- if prefix:
- ui.write('\0')
-
-def base(ui, repo, node1, node2):
- """output common ancestor information"""
- node1 = repo.lookup(node1)
- node2 = repo.lookup(node2)
- n = repo.changelog.ancestor(node1, node2)
- ui.write(short(n) + "\n")
-
-def catfile(ui, repo, type=None, r=None, **opts):
- """cat a specific revision"""
- # in stdin mode, every line except the commit is prefixed with two
- # spaces. This way the our caller can find the commit without magic
- # strings
- #
- prefix = ""
- if opts['stdin']:
- try:
- (type, r) = raw_input().split(' ')
- prefix = " "
- except EOFError:
- return
-
- else:
- if not type or not r:
- ui.warn(_("cat-file: type or revision not supplied\n"))
- commands.help_(ui, 'cat-file')
-
- while r:
- if type != "commit":
- ui.warn(_("aborting hg cat-file only understands commits\n"))
- return 1
- n = repo.lookup(r)
- catcommit(ui, repo, n, prefix)
- if opts['stdin']:
- try:
- (type, r) = raw_input().split(' ')
- except EOFError:
- break
- else:
- break
-
-# git rev-tree is a confusing thing. You can supply a number of
-# commit sha1s on the command line, and it walks the commit history
-# telling you which commits are reachable from the supplied ones via
-# a bitmask based on arg position.
-# 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 = len(repo)
- i = count
- l = [0] * 100
- chunk = 100
- while True:
- if chunk > i:
- chunk = i
- i = 0
- else:
- i -= chunk
-
- for x in xrange(chunk):
- if i + x >= count:
- l[chunk - x:] = [0] * (chunk - x)
- break
- if full != None:
- l[x] = repo[i + x]
- l[x].changeset() # force reading
- else:
- l[x] = 1
- for x in xrange(chunk - 1, -1, -1):
- if l[x] != 0:
- yield (i + x, full != None and l[x] or None)
- if i == 0:
- break
-
- # calculate and return the reachability bitmask for sha
- def is_reachable(ar, reachable, sha):
- if len(ar) == 0:
- return 1
- mask = 0
- for i in xrange(len(ar)):
- if sha in reachable[i]:
- mask |= 1 << i
-
- return mask
-
- reachable = []
- stop_sha1 = []
- want_sha1 = []
- count = 0
-
- # figure out which commits they are asking for and which ones they
- # want us to stop on
- for i, arg in enumerate(args):
- if arg.startswith('^'):
- s = repo.lookup(arg[1:])
- stop_sha1.append(s)
- want_sha1.append(s)
- elif arg != 'HEAD':
- want_sha1.append(repo.lookup(arg))
-
- # calculate the graph for the supplied commits
- for i, n in enumerate(want_sha1):
- reachable.append(set())
- visit = [n]
- reachable[i].add(n)
- while visit:
- n = visit.pop(0)
- if n in stop_sha1:
- continue
- for p in repo.changelog.parents(n):
- if p not in reachable[i]:
- reachable[i].add(p)
- visit.append(p)
- if p in stop_sha1:
- continue
-
- # walk the repository looking for commits that are in our
- # reachability graph
- for i, ctx in chlogwalk():
- n = repo.changelog.node(i)
- mask = is_reachable(want_sha1, reachable, n)
- if mask:
- parentstr = ""
- if parents:
- pp = repo.changelog.parents(n)
- if pp[0] != nullid:
- parentstr += " " + short(pp[0])
- if pp[1] != nullid:
- parentstr += " " + short(pp[1])
- if not full:
- ui.write("%s%s\n" % (short(n), parentstr))
- elif full == "commit":
- ui.write("%s%s\n" % (short(n), parentstr))
- catcommit(ui, repo, n, ' ', ctx)
- else:
- (p1, p2) = repo.changelog.parents(n)
- (h, h1, h2) = map(short, (n, p1, p2))
- (i1, i2) = map(repo.changelog.rev, (p1, p2))
-
- date = ctx.date()[0]
- ui.write("%s %s:%s" % (date, h, mask))
- mask = is_reachable(want_sha1, reachable, p1)
- if i1 != nullrev and mask > 0:
- ui.write("%s:%s " % (h1, mask)),
- mask = is_reachable(want_sha1, reachable, p2)
- if i2 != nullrev and mask > 0:
- ui.write("%s:%s " % (h2, mask))
- ui.write("\n")
- if maxnr and count >= maxnr:
- break
- count += 1
-
-def revparse(ui, repo, *revs, **opts):
- """parse given revisions"""
- def revstr(rev):
- if rev == 'HEAD':
- rev = 'tip'
- return revlog.hex(repo.lookup(rev))
-
- for r in revs:
- revrange = r.split(':', 1)
- ui.write('%s\n' % revstr(revrange[0]))
- if len(revrange) == 2:
- ui.write('^%s\n' % revstr(revrange[1]))
-
-# git rev-list tries to order things by date, and has the ability to stop
-# at a given commit without walking the whole repo. TODO add the stop
-# parameter
-def revlist(ui, repo, *revs, **opts):
- """print revisions"""
- if opts['header']:
- full = "commit"
- else:
- full = None
- copy = [x for x in revs]
- revtree(ui, copy, repo, full, opts['max_count'], opts['parents'])
-
-def config(ui, repo, **opts):
- """print extension options"""
- def writeopt(name, value):
- ui.write('k=%s\nv=%s\n' % (name, value))
-
- writeopt('vdiff', ui.config('hgk', 'vdiff', ''))
-
-
-def view(ui, repo, *etc, **opts):
- "start interactive history viewer"
- os.chdir(repo.root)
- optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
- cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
- ui.debug("running %s\n" % cmd)
- util.system(cmd)
-
-cmdtable = {
- "^view":
- (view,
- [('l', 'limit', '',
- _('limit number of changes displayed'), _('NUM'))],
- _('hg view [-l LIMIT] [REVRANGE]')),
- "debug-diff-tree":
- (difftree,
- [('p', 'patch', None, _('generate patch')),
- ('r', 'recursive', None, _('recursive')),
- ('P', 'pretty', None, _('pretty')),
- ('s', 'stdin', None, _('stdin')),
- ('C', 'copy', None, _('detect copies')),
- ('S', 'search', "", _('search'))],
- _('hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]...')),
- "debug-cat-file":
- (catfile,
- [('s', 'stdin', None, _('stdin'))],
- _('hg debug-cat-file [OPTION]... TYPE FILE')),
- "debug-config":
- (config, [], _('hg debug-config')),
- "debug-merge-base":
- (base, [], _('hg debug-merge-base REV REV')),
- "debug-rev-parse":
- (revparse,
- [('', 'default', '', _('ignored'))],
- _('hg debug-rev-parse REV')),
- "debug-rev-list":
- (revlist,
- [('H', 'header', None, _('header')),
- ('t', 'topo-order', None, _('topo-order')),
- ('p', 'parents', None, _('parents')),
- ('n', 'max-count', 0, _('max-count'))],
- _('hg debug-rev-list [OPTION]... REV...')),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.pyo
deleted file mode 100644
index 97aa394..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/hgk.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.py
deleted file mode 100644
index 55e3c18..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# highlight - syntax highlighting in hgweb, based on Pygments
-#
-# Copyright 2008, 2009 Patrick Mezard <pmezard@gmail.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-#
-# The original module was split in an interface and an implementation
-# file to defer pygments loading and speedup extension setup.
-
-"""syntax highlighting for hgweb (requires Pygments)
-
-It depends on the Pygments syntax highlighting library:
-http://pygments.org/
-
-There is a single configuration option::
-
- [web]
- pygments_style = <style>
-
-The default is 'colorful'.
-"""
-
-import highlight
-from mercurial.hgweb import webcommands, webutil, common
-from mercurial import extensions, encoding
-
-def filerevision_highlight(orig, web, tmpl, fctx):
- mt = ''.join(tmpl('mimetype', encoding=encoding.encoding))
- # only pygmentize for mimetype containing 'html' so we both match
- # 'text/html' and possibly 'application/xhtml+xml' in the future
- # so that we don't have to touch the extension when the mimetype
- # for a template changes; also hgweb optimizes the case that a
- # raw file is sent using rawfile() and doesn't call us, so we
- # can't clash with the file's content-type here in case we
- # pygmentize a html file
- if 'html' in mt:
- style = web.config('web', 'pygments_style', 'colorful')
- highlight.pygmentize('fileline', fctx, style, tmpl)
- return orig(web, tmpl, fctx)
-
-def annotate_highlight(orig, web, req, tmpl):
- mt = ''.join(tmpl('mimetype', encoding=encoding.encoding))
- if 'html' in mt:
- fctx = webutil.filectx(web.repo, req)
- style = web.config('web', 'pygments_style', 'colorful')
- highlight.pygmentize('annotateline', fctx, style, tmpl)
- return orig(web, req, tmpl)
-
-def generate_css(web, req, tmpl):
- pg_style = web.config('web', 'pygments_style', 'colorful')
- fmter = highlight.HtmlFormatter(style = pg_style)
- req.respond(common.HTTP_OK, 'text/css')
- return ['/* pygments_style = %s */\n\n' % pg_style, fmter.get_style_defs('')]
-
-def extsetup():
- # monkeypatch in the new version
- extensions.wrapfunction(webcommands, '_filerevision', filerevision_highlight)
- extensions.wrapfunction(webcommands, 'annotate', annotate_highlight)
- webcommands.highlightcss = generate_css
- webcommands.__all__.append('highlightcss')
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.pyo
deleted file mode 100644
index eb0ba63..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/__init__.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.py
deleted file mode 100644
index a8265cf..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# highlight.py - highlight extension implementation file
-#
-# Copyright 2007-2009 Adam Hupp <adam@hupp.org> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-#
-# The original module was split in an interface and an implementation
-# file to defer pygments loading and speedup extension setup.
-
-from mercurial import demandimport
-demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__'])
-from mercurial import util, encoding
-
-from pygments import highlight
-from pygments.util import ClassNotFound
-from pygments.lexers import guess_lexer, guess_lexer_for_filename, TextLexer
-from pygments.formatters import HtmlFormatter
-
-SYNTAX_CSS = ('\n<link rel="stylesheet" href="{url}highlightcss" '
- 'type="text/css" />')
-
-def pygmentize(field, fctx, style, tmpl):
-
- # append a <link ...> to the syntax highlighting css
- old_header = tmpl.load('header')
- if SYNTAX_CSS not in old_header:
- new_header = old_header + SYNTAX_CSS
- tmpl.cache['header'] = new_header
-
- text = fctx.data()
- if util.binary(text):
- return
-
- # Pygments is best used with Unicode strings:
- # <http://pygments.org/docs/unicode/>
- text = text.decode(encoding.encoding, 'replace')
-
- # To get multi-line strings right, we can't format line-by-line
- try:
- lexer = guess_lexer_for_filename(fctx.path(), text[:1024])
- except (ClassNotFound, ValueError):
- try:
- lexer = guess_lexer(text[:1024])
- except (ClassNotFound, ValueError):
- lexer = TextLexer()
-
- formatter = HtmlFormatter(style=style)
-
- colorized = highlight(text, lexer, formatter)
- # strip wrapping div
- colorized = colorized[:colorized.find('\n</pre>')]
- colorized = colorized[colorized.find('<pre>')+5:]
- coloriter = (s.encode(encoding.encoding, 'replace')
- for s in colorized.splitlines())
-
- tmpl.filters['colorize'] = lambda x: coloriter.next()
-
- oldl = tmpl.cache[field]
- newl = oldl.replace('line|escape', 'line|colorize')
- tmpl.cache[field] = newl
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.pyo
deleted file mode 100644
index 7d10f48..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/highlight/highlight.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.py
deleted file mode 100644
index 60c4255..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# interhg.py - interhg
-#
-# Copyright 2007 OHASHI Hideya <ohachige@gmail.com>
-#
-# Contributor(s):
-# Edward Lee <edward.lee@engineering.uiuc.edu>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''expand expressions into changelog and summaries
-
-This extension allows the use of a special syntax in summaries, which
-will be automatically expanded into links or any other arbitrary
-expression, much like InterWiki does.
-
-A few example patterns (link to bug tracking, etc.) that may be used
-in your hgrc::
-
- [interhg]
- issues = s!issue(\\d+)!<a href="http://bts/issue\\1">issue\\1</a>!
- bugzilla = s!((?:bug|b=|(?=#?\\d{4,}))(?:\\s*#?)(\\d+))!<a..=\\2">\\1</a>!i
- boldify = s!(^|\\s)#(\\d+)\\b! <b>#\\2</b>!
-'''
-
-import re
-from mercurial.hgweb import hgweb_mod
-from mercurial import templatefilters, extensions
-from mercurial.i18n import _
-
-interhg_table = []
-
-def uisetup(ui):
- orig_escape = templatefilters.filters["escape"]
-
- def interhg_escape(x):
- escstr = orig_escape(x)
- for regexp, format in interhg_table:
- escstr = regexp.sub(format, escstr)
- return escstr
-
- templatefilters.filters["escape"] = interhg_escape
-
-def interhg_refresh(orig, self, *args, **kwargs):
- interhg_table[:] = []
- for key, pattern in self.repo.ui.configitems('interhg'):
- # grab the delimiter from the character after the "s"
- unesc = pattern[1]
- delim = re.escape(unesc)
-
- # identify portions of the pattern, taking care to avoid escaped
- # delimiters. the replace format and flags are optional, but delimiters
- # are required.
- match = re.match(r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
- % (delim, delim, delim), pattern)
- if not match:
- self.repo.ui.warn(_("interhg: invalid pattern for %s: %s\n")
- % (key, pattern))
- continue
-
- # we need to unescape the delimiter for regexp and format
- delim_re = re.compile(r'(?<!\\)\\%s' % delim)
- regexp = delim_re.sub(unesc, match.group(1))
- format = delim_re.sub(unesc, match.group(2))
-
- # the pattern allows for 6 regexp flags, so set them if necessary
- flagin = match.group(3)
- flags = 0
- if flagin:
- for flag in flagin.upper():
- flags |= re.__dict__[flag]
-
- try:
- regexp = re.compile(regexp, flags)
- interhg_table.append((regexp, format))
- except re.error:
- self.repo.ui.warn(_("interhg: invalid regexp for %s: %s\n")
- % (key, regexp))
- return orig(self, *args, **kwargs)
-
-extensions.wrapfunction(hgweb_mod.hgweb, 'refresh', interhg_refresh)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.pyo
deleted file mode 100644
index c5dd4d7..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/interhg.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.py
deleted file mode 100644
index 9060714..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.py
+++ /dev/null
@@ -1,649 +0,0 @@
-# keyword.py - $Keyword$ expansion for Mercurial
-#
-# Copyright 2007-2010 Christian Ebert <blacktrash@gmx.net>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-#
-# $Id$
-#
-# Keyword expansion hack against the grain of a DSCM
-#
-# There are many good reasons why this is not needed in a distributed
-# SCM, still it may be useful in very small projects based on single
-# files (like LaTeX packages), that are mostly addressed to an
-# audience not running a version control system.
-#
-# For in-depth discussion refer to
-# <http://mercurial.selenic.com/wiki/KeywordPlan>.
-#
-# Keyword expansion is based on Mercurial's changeset template mappings.
-#
-# Binary files are not touched.
-#
-# Files to act upon/ignore are specified in the [keyword] section.
-# Customized keyword template mappings in the [keywordmaps] section.
-#
-# Run "hg help keyword" and "hg kwdemo" to get info on configuration.
-
-'''expand keywords in tracked files
-
-This extension expands RCS/CVS-like or self-customized $Keywords$ in
-tracked text files selected by your configuration.
-
-Keywords are only expanded in local repositories and not stored in the
-change history. The mechanism can be regarded as a convenience for the
-current user or for archive distribution.
-
-Keywords expand to the changeset data pertaining to the latest change
-relative to the working directory parent of each file.
-
-Configuration is done in the [keyword], [keywordset] and [keywordmaps]
-sections of hgrc files.
-
-Example::
-
- [keyword]
- # expand keywords in every python file except those matching "x*"
- **.py =
- x* = ignore
-
- [keywordset]
- # prefer svn- over cvs-like default keywordmaps
- svn = True
-
-.. note::
- The more specific you are in your filename patterns the less you
- lose speed in huge repositories.
-
-For [keywordmaps] template mapping and expansion demonstration and
-control run :hg:`kwdemo`. See :hg:`help templates` for a list of
-available templates and filters.
-
-Three additional date template filters are provided::
-
- utcdate "2006/09/18 15:13:13"
- svnutcdate "2006-09-18 15:13:13Z"
- svnisodate "2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)"
-
-The default template mappings (view with :hg:`kwdemo -d`) can be
-replaced with customized keywords and templates. Again, run
-:hg:`kwdemo` to control the results of your configuration changes.
-
-Before changing/disabling active keywords, run :hg:`kwshrink` to avoid
-the risk of inadvertently storing expanded keywords in the change
-history.
-
-To force expansion after enabling it, or a configuration change, run
-:hg:`kwexpand`.
-
-Expansions spanning more than one line and incremental expansions,
-like CVS' $Log$, are not supported. A keyword template map "Log =
-{desc}" expands to the first line of the changeset description.
-'''
-
-from mercurial import commands, context, cmdutil, dispatch, filelog, extensions
-from mercurial import localrepo, match, patch, templatefilters, templater, util
-from mercurial.hgweb import webcommands
-from mercurial.i18n import _
-import os, re, shutil, tempfile
-
-commands.optionalrepo += ' kwdemo'
-
-# hg commands that do not act on keywords
-nokwcommands = ('add addremove annotate bundle export grep incoming init log'
- ' outgoing push tip verify convert email glog')
-
-# hg commands that trigger expansion only when writing to working dir,
-# not when reading filelog, and unexpand when reading from working dir
-restricted = 'merge kwexpand kwshrink record qrecord resolve transplant'
-
-# names of extensions using dorecord
-recordextensions = 'record'
-
-# date like in cvs' $Date
-utcdate = lambda x: util.datestr((x[0], 0), '%Y/%m/%d %H:%M:%S')
-# date like in svn's $Date
-svnisodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
-# date like in svn's $Id
-svnutcdate = lambda x: util.datestr((x[0], 0), '%Y-%m-%d %H:%M:%SZ')
-
-# make keyword tools accessible
-kwtools = {'templater': None, 'hgcmd': ''}
-
-
-def _defaultkwmaps(ui):
- '''Returns default keywordmaps according to keywordset configuration.'''
- templates = {
- 'Revision': '{node|short}',
- 'Author': '{author|user}',
- }
- kwsets = ({
- 'Date': '{date|utcdate}',
- 'RCSfile': '{file|basename},v',
- 'RCSFile': '{file|basename},v', # kept for backwards compatibility
- # with hg-keyword
- 'Source': '{root}/{file},v',
- 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
- 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
- }, {
- 'Date': '{date|svnisodate}',
- 'Id': '{file|basename},v {node|short} {date|svnutcdate} {author|user}',
- 'LastChangedRevision': '{node|short}',
- 'LastChangedBy': '{author|user}',
- 'LastChangedDate': '{date|svnisodate}',
- })
- templates.update(kwsets[ui.configbool('keywordset', 'svn')])
- return templates
-
-def _shrinktext(text, subfunc):
- '''Helper for keyword expansion removal in text.
- Depending on subfunc also returns number of substitutions.'''
- return subfunc(r'$\1$', text)
-
-def _preselect(wstatus, changed):
- '''Retrieves modfied and added files from a working directory state
- and returns the subset of each contained in given changed files
- retrieved from a change context.'''
- modified, added = wstatus[:2]
- modified = [f for f in modified if f in changed]
- added = [f for f in added if f in changed]
- return modified, added
-
-
-class kwtemplater(object):
- '''
- Sets up keyword templates, corresponding keyword regex, and
- provides keyword substitution functions.
- '''
-
- def __init__(self, ui, repo, inc, exc):
- self.ui = ui
- self.repo = repo
- self.match = match.match(repo.root, '', [], inc, exc)
- self.restrict = kwtools['hgcmd'] in restricted.split()
- self.record = False
-
- kwmaps = self.ui.configitems('keywordmaps')
- if kwmaps: # override default templates
- self.templates = dict((k, templater.parsestring(v, False))
- for k, v in kwmaps)
- else:
- self.templates = _defaultkwmaps(self.ui)
- escaped = '|'.join(map(re.escape, self.templates.keys()))
- self.re_kw = re.compile(r'\$(%s)\$' % escaped)
- self.re_kwexp = re.compile(r'\$(%s): [^$\n\r]*? \$' % escaped)
-
- templatefilters.filters.update({'utcdate': utcdate,
- 'svnisodate': svnisodate,
- 'svnutcdate': svnutcdate})
-
- def substitute(self, data, path, ctx, subfunc):
- '''Replaces keywords in data with expanded template.'''
- def kwsub(mobj):
- kw = mobj.group(1)
- ct = cmdutil.changeset_templater(self.ui, self.repo,
- False, None, '', False)
- ct.use_template(self.templates[kw])
- self.ui.pushbuffer()
- ct.show(ctx, root=self.repo.root, file=path)
- ekw = templatefilters.firstline(self.ui.popbuffer())
- return '$%s: %s $' % (kw, ekw)
- return subfunc(kwsub, data)
-
- def expand(self, path, node, data):
- '''Returns data with keywords expanded.'''
- if not self.restrict and self.match(path) and not util.binary(data):
- ctx = self.repo.filectx(path, fileid=node).changectx()
- return self.substitute(data, path, ctx, self.re_kw.sub)
- return data
-
- def iskwfile(self, cand, ctx):
- '''Returns subset of candidates which are configured for keyword
- expansion are not symbolic links.'''
- return [f for f in cand if self.match(f) and not 'l' in ctx.flags(f)]
-
- def overwrite(self, ctx, candidates, lookup, expand, rekw=False):
- '''Overwrites selected files expanding/shrinking keywords.'''
- if self.restrict or lookup or self.record: # exclude kw_copy
- candidates = self.iskwfile(candidates, ctx)
- if not candidates:
- return
- kwcmd = self.restrict and lookup # kwexpand/kwshrink
- if self.restrict or expand and lookup:
- mf = ctx.manifest()
- fctx = ctx
- subn = (self.restrict or rekw) and self.re_kw.subn or self.re_kwexp.subn
- msg = (expand and _('overwriting %s expanding keywords\n')
- or _('overwriting %s shrinking keywords\n'))
- for f in candidates:
- if self.restrict:
- data = self.repo.file(f).read(mf[f])
- else:
- data = self.repo.wread(f)
- if util.binary(data):
- continue
- if expand:
- if lookup:
- fctx = self.repo.filectx(f, fileid=mf[f]).changectx()
- data, found = self.substitute(data, f, fctx, subn)
- elif self.restrict:
- found = self.re_kw.search(data)
- else:
- data, found = _shrinktext(data, subn)
- if found:
- self.ui.note(msg % f)
- self.repo.wwrite(f, data, ctx.flags(f))
- if kwcmd:
- self.repo.dirstate.normal(f)
- elif self.record:
- self.repo.dirstate.normallookup(f)
-
- def shrink(self, fname, text):
- '''Returns text with all keyword substitutions removed.'''
- if self.match(fname) and not util.binary(text):
- return _shrinktext(text, self.re_kwexp.sub)
- return text
-
- def shrinklines(self, fname, lines):
- '''Returns lines with keyword substitutions removed.'''
- if self.match(fname):
- text = ''.join(lines)
- if not util.binary(text):
- return _shrinktext(text, self.re_kwexp.sub).splitlines(True)
- return lines
-
- def wread(self, fname, data):
- '''If in restricted mode returns data read from wdir with
- keyword substitutions removed.'''
- return self.restrict and self.shrink(fname, data) or data
-
-class kwfilelog(filelog.filelog):
- '''
- Subclass of filelog to hook into its read, add, cmp methods.
- Keywords are "stored" unexpanded, and processed on reading.
- '''
- def __init__(self, opener, kwt, path):
- super(kwfilelog, self).__init__(opener, path)
- self.kwt = kwt
- self.path = path
-
- def read(self, node):
- '''Expands keywords when reading filelog.'''
- data = super(kwfilelog, self).read(node)
- if self.renamed(node):
- return data
- return self.kwt.expand(self.path, node, data)
-
- def add(self, text, meta, tr, link, p1=None, p2=None):
- '''Removes keyword substitutions when adding to filelog.'''
- text = self.kwt.shrink(self.path, text)
- return super(kwfilelog, self).add(text, meta, tr, link, p1, p2)
-
- def cmp(self, node, text):
- '''Removes keyword substitutions for comparison.'''
- text = self.kwt.shrink(self.path, text)
- return super(kwfilelog, self).cmp(node, text)
-
-def _status(ui, repo, kwt, *pats, **opts):
- '''Bails out if [keyword] configuration is not active.
- Returns status of working directory.'''
- if kwt:
- return repo.status(match=cmdutil.match(repo, pats, opts), clean=True,
- unknown=opts.get('unknown') or opts.get('all'))
- if ui.configitems('keyword'):
- raise util.Abort(_('[keyword] patterns cannot match'))
- raise util.Abort(_('no [keyword] patterns configured'))
-
-def _kwfwrite(ui, repo, expand, *pats, **opts):
- '''Selects files and passes them to kwtemplater.overwrite.'''
- wctx = repo[None]
- if len(wctx.parents()) > 1:
- raise util.Abort(_('outstanding uncommitted merge'))
- kwt = kwtools['templater']
- wlock = repo.wlock()
- try:
- status = _status(ui, repo, kwt, *pats, **opts)
- modified, added, removed, deleted, unknown, ignored, clean = status
- if modified or added or removed or deleted:
- raise util.Abort(_('outstanding uncommitted changes'))
- kwt.overwrite(wctx, clean, True, expand)
- finally:
- wlock.release()
-
-def demo(ui, repo, *args, **opts):
- '''print [keywordmaps] configuration and an expansion example
-
- Show current, custom, or default keyword template maps and their
- expansions.
-
- Extend the current configuration by specifying maps as arguments
- and using -f/--rcfile to source an external hgrc file.
-
- Use -d/--default to disable current configuration.
-
- See :hg:`help templates` for information on templates and filters.
- '''
- def demoitems(section, items):
- ui.write('[%s]\n' % section)
- for k, v in sorted(items):
- ui.write('%s = %s\n' % (k, v))
-
- fn = 'demo.txt'
- tmpdir = tempfile.mkdtemp('', 'kwdemo.')
- ui.note(_('creating temporary repository at %s\n') % tmpdir)
- repo = localrepo.localrepository(ui, tmpdir, True)
- ui.setconfig('keyword', fn, '')
-
- uikwmaps = ui.configitems('keywordmaps')
- if args or opts.get('rcfile'):
- ui.status(_('\n\tconfiguration using custom keyword template maps\n'))
- if uikwmaps:
- ui.status(_('\textending current template maps\n'))
- if opts.get('default') or not uikwmaps:
- ui.status(_('\toverriding default template maps\n'))
- if opts.get('rcfile'):
- ui.readconfig(opts.get('rcfile'))
- if args:
- # simulate hgrc parsing
- rcmaps = ['[keywordmaps]\n'] + [a + '\n' for a in args]
- fp = repo.opener('hgrc', 'w')
- fp.writelines(rcmaps)
- fp.close()
- ui.readconfig(repo.join('hgrc'))
- kwmaps = dict(ui.configitems('keywordmaps'))
- elif opts.get('default'):
- ui.status(_('\n\tconfiguration using default keyword template maps\n'))
- kwmaps = _defaultkwmaps(ui)
- if uikwmaps:
- ui.status(_('\tdisabling current template maps\n'))
- for k, v in kwmaps.iteritems():
- ui.setconfig('keywordmaps', k, v)
- else:
- ui.status(_('\n\tconfiguration using current keyword template maps\n'))
- kwmaps = dict(uikwmaps) or _defaultkwmaps(ui)
-
- uisetup(ui)
- reposetup(ui, repo)
- ui.write('[extensions]\nkeyword =\n')
- demoitems('keyword', ui.configitems('keyword'))
- demoitems('keywordmaps', kwmaps.iteritems())
- keywords = '$' + '$\n$'.join(sorted(kwmaps.keys())) + '$\n'
- repo.wopener(fn, 'w').write(keywords)
- repo[None].add([fn])
- ui.note(_('\nkeywords written to %s:\n') % fn)
- ui.note(keywords)
- repo.dirstate.setbranch('demobranch')
- for name, cmd in ui.configitems('hooks'):
- if name.split('.', 1)[0].find('commit') > -1:
- repo.ui.setconfig('hooks', name, '')
- msg = _('hg keyword configuration and expansion example')
- ui.note("hg ci -m '%s'\n" % msg)
- repo.commit(text=msg)
- ui.status(_('\n\tkeywords expanded\n'))
- ui.write(repo.wread(fn))
- shutil.rmtree(tmpdir, ignore_errors=True)
-
-def expand(ui, repo, *pats, **opts):
- '''expand keywords in the working directory
-
- Run after (re)enabling keyword expansion.
-
- kwexpand refuses to run if given files contain local changes.
- '''
- # 3rd argument sets expansion to True
- _kwfwrite(ui, repo, True, *pats, **opts)
-
-def files(ui, repo, *pats, **opts):
- '''show files configured for keyword expansion
-
- List which files in the working directory are matched by the
- [keyword] configuration patterns.
-
- Useful to prevent inadvertent keyword expansion and to speed up
- execution by including only files that are actual candidates for
- expansion.
-
- See :hg:`help keyword` on how to construct patterns both for
- inclusion and exclusion of files.
-
- With -A/--all and -v/--verbose the codes used to show the status
- of files are::
-
- K = keyword expansion candidate
- k = keyword expansion candidate (not tracked)
- I = ignored
- i = ignored (not tracked)
- '''
- kwt = kwtools['templater']
- status = _status(ui, repo, kwt, *pats, **opts)
- cwd = pats and repo.getcwd() or ''
- modified, added, removed, deleted, unknown, ignored, clean = status
- files = []
- if not opts.get('unknown') or opts.get('all'):
- files = sorted(modified + added + clean)
- wctx = repo[None]
- kwfiles = kwt.iskwfile(files, wctx)
- kwunknown = kwt.iskwfile(unknown, wctx)
- if not opts.get('ignore') or opts.get('all'):
- showfiles = kwfiles, kwunknown
- else:
- showfiles = [], []
- if opts.get('all') or opts.get('ignore'):
- showfiles += ([f for f in files if f not in kwfiles],
- [f for f in unknown if f not in kwunknown])
- for char, filenames in zip('KkIi', showfiles):
- fmt = (opts.get('all') or ui.verbose) and '%s %%s\n' % char or '%s\n'
- for f in filenames:
- ui.write(fmt % repo.pathto(f, cwd))
-
-def shrink(ui, repo, *pats, **opts):
- '''revert expanded keywords in the working directory
-
- Run before changing/disabling active keywords or if you experience
- problems with :hg:`import` or :hg:`merge`.
-
- kwshrink refuses to run if given files contain local changes.
- '''
- # 3rd argument sets expansion to False
- _kwfwrite(ui, repo, False, *pats, **opts)
-
-
-def uisetup(ui):
- ''' Monkeypatches dispatch._parse to retrieve user command.'''
-
- def kwdispatch_parse(orig, ui, args):
- '''Monkeypatch dispatch._parse to obtain running hg command.'''
- cmd, func, args, options, cmdoptions = orig(ui, args)
- kwtools['hgcmd'] = cmd
- return cmd, func, args, options, cmdoptions
-
- extensions.wrapfunction(dispatch, '_parse', kwdispatch_parse)
-
-def reposetup(ui, repo):
- '''Sets up repo as kwrepo for keyword substitution.
- Overrides file method to return kwfilelog instead of filelog
- if file matches user configuration.
- Wraps commit to overwrite configured files with updated
- keyword substitutions.
- Monkeypatches patch and webcommands.'''
-
- try:
- if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
- or '.hg' in util.splitpath(repo.root)
- or repo._url.startswith('bundle:')):
- return
- except AttributeError:
- pass
-
- inc, exc = [], ['.hg*']
- for pat, opt in ui.configitems('keyword'):
- if opt != 'ignore':
- inc.append(pat)
- else:
- exc.append(pat)
- if not inc:
- return
-
- kwtools['templater'] = kwt = kwtemplater(ui, repo, inc, exc)
-
- class kwrepo(repo.__class__):
- def file(self, f):
- if f[0] == '/':
- f = f[1:]
- return kwfilelog(self.sopener, kwt, f)
-
- def wread(self, filename):
- data = super(kwrepo, self).wread(filename)
- return kwt.wread(filename, data)
-
- def commit(self, *args, **opts):
- # use custom commitctx for user commands
- # other extensions can still wrap repo.commitctx directly
- self.commitctx = self.kwcommitctx
- try:
- return super(kwrepo, self).commit(*args, **opts)
- finally:
- del self.commitctx
-
- def kwcommitctx(self, ctx, error=False):
- n = super(kwrepo, self).commitctx(ctx, error)
- # no lock needed, only called from repo.commit() which already locks
- if not kwt.record:
- restrict = kwt.restrict
- kwt.restrict = True
- kwt.overwrite(self[n], sorted(ctx.added() + ctx.modified()),
- False, True)
- kwt.restrict = restrict
- return n
-
- def rollback(self, dryrun=False):
- wlock = self.wlock()
- try:
- if not dryrun:
- changed = self['.'].files()
- ret = super(kwrepo, self).rollback(dryrun)
- if not dryrun:
- ctx = self['.']
- modified, added = _preselect(self[None].status(), changed)
- kwt.overwrite(ctx, modified, True, True)
- kwt.overwrite(ctx, added, True, False)
- return ret
- finally:
- wlock.release()
-
- # monkeypatches
- def kwpatchfile_init(orig, self, ui, fname, opener,
- missing=False, eolmode=None):
- '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
- rejects or conflicts due to expanded keywords in working dir.'''
- orig(self, ui, fname, opener, missing, eolmode)
- # shrink keywords read from working dir
- self.lines = kwt.shrinklines(self.fname, self.lines)
-
- def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None,
- opts=None, prefix=''):
- '''Monkeypatch patch.diff to avoid expansion.'''
- kwt.restrict = True
- return orig(repo, node1, node2, match, changes, opts, prefix)
-
- def kwweb_skip(orig, web, req, tmpl):
- '''Wraps webcommands.x turning off keyword expansion.'''
- kwt.match = util.never
- return orig(web, req, tmpl)
-
- def kw_copy(orig, ui, repo, pats, opts, rename=False):
- '''Wraps cmdutil.copy so that copy/rename destinations do not
- contain expanded keywords.
- Note that the source of a regular file destination may also be a
- symlink:
- hg cp sym x -> x is symlink
- cp sym x; hg cp -A sym x -> x is file (maybe expanded keywords)
- For the latter we have to follow the symlink to find out whether its
- target is configured for expansion and we therefore must unexpand the
- keywords in the destination.'''
- orig(ui, repo, pats, opts, rename)
- if opts.get('dry_run'):
- return
- wctx = repo[None]
- cwd = repo.getcwd()
-
- def haskwsource(dest):
- '''Returns true if dest is a regular file and configured for
- expansion or a symlink which points to a file configured for
- expansion. '''
- source = repo.dirstate.copied(dest)
- if 'l' in wctx.flags(source):
- source = util.canonpath(repo.root, cwd,
- os.path.realpath(source))
- return kwt.match(source)
-
- candidates = [f for f in repo.dirstate.copies() if
- not 'l' in wctx.flags(f) and haskwsource(f)]
- kwt.overwrite(wctx, candidates, False, False)
-
- def kw_dorecord(orig, ui, repo, commitfunc, *pats, **opts):
- '''Wraps record.dorecord expanding keywords after recording.'''
- wlock = repo.wlock()
- try:
- # record returns 0 even when nothing has changed
- # therefore compare nodes before and after
- kwt.record = True
- ctx = repo['.']
- wstatus = repo[None].status()
- ret = orig(ui, repo, commitfunc, *pats, **opts)
- recctx = repo['.']
- if ctx != recctx:
- modified, added = _preselect(wstatus, recctx.files())
- kwt.restrict = False
- kwt.overwrite(recctx, modified, False, True)
- kwt.overwrite(recctx, added, False, True, True)
- kwt.restrict = True
- return ret
- finally:
- wlock.release()
-
- repo.__class__ = kwrepo
-
- def kwfilectx_cmp(orig, self, fctx):
- # keyword affects data size, comparing wdir and filelog size does
- # not make sense
- if (fctx._filerev is None and
- (self._repo._encodefilterpats or
- kwt.match(fctx.path()) and not 'l' in fctx.flags()) or
- self.size() == fctx.size()):
- return self._filelog.cmp(self._filenode, fctx.data())
- return True
-
- extensions.wrapfunction(context.filectx, 'cmp', kwfilectx_cmp)
- extensions.wrapfunction(patch.patchfile, '__init__', kwpatchfile_init)
- extensions.wrapfunction(patch, 'diff', kw_diff)
- extensions.wrapfunction(cmdutil, 'copy', kw_copy)
- for c in 'annotate changeset rev filediff diff'.split():
- extensions.wrapfunction(webcommands, c, kwweb_skip)
- for name in recordextensions.split():
- try:
- record = extensions.find(name)
- extensions.wrapfunction(record, 'dorecord', kw_dorecord)
- except KeyError:
- pass
-
-cmdtable = {
- 'kwdemo':
- (demo,
- [('d', 'default', None, _('show default keyword template maps')),
- ('f', 'rcfile', '',
- _('read maps from rcfile'), _('FILE'))],
- _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')),
- 'kwexpand': (expand, commands.walkopts,
- _('hg kwexpand [OPTION]... [FILE]...')),
- 'kwfiles':
- (files,
- [('A', 'all', None, _('show keyword status flags of all files')),
- ('i', 'ignore', None, _('show files excluded from expansion')),
- ('u', 'unknown', None, _('only show unknown (not tracked) files')),
- ] + commands.walkopts,
- _('hg kwfiles [OPTION]... [FILE]...')),
- 'kwshrink': (shrink, commands.walkopts,
- _('hg kwshrink [OPTION]... [FILE]...')),
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.pyo
deleted file mode 100644
index e6e44ac..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/keyword.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.py
deleted file mode 100644
index 5137089..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.py
+++ /dev/null
@@ -1,3211 +0,0 @@
-# mq.py - patch queues for mercurial
-#
-# Copyright 2005, 2006 Chris Mason <mason@suse.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''manage a stack of patches
-
-This extension lets you work with a stack of patches in a Mercurial
-repository. It manages two stacks of patches - all known patches, and
-applied patches (subset of known patches).
-
-Known patches are represented as patch files in the .hg/patches
-directory. Applied patches are both patch files and changesets.
-
-Common tasks (use :hg:`help command` for more details)::
-
- create new patch qnew
- import existing patch qimport
-
- print patch series qseries
- print applied patches qapplied
-
- add known patch to applied stack qpush
- remove patch from applied stack qpop
- refresh contents of top applied patch qrefresh
-
-By default, mq will automatically use git patches when required to
-avoid losing file mode changes, copy records, binary files or empty
-files creations or deletions. This behaviour can be configured with::
-
- [mq]
- git = auto/keep/yes/no
-
-If set to 'keep', mq will obey the [diff] section configuration while
-preserving existing git patches upon qrefresh. If set to 'yes' or
-'no', mq will override the [diff] section and always generate git or
-regular patches, possibly losing data in the second case.
-
-You will by default be managing a patch queue named "patches". You can
-create other, independent patch queues with the :hg:`qqueue` command.
-'''
-
-from mercurial.i18n import _
-from mercurial.node import bin, hex, short, nullid, nullrev
-from mercurial.lock import release
-from mercurial import commands, cmdutil, hg, patch, util
-from mercurial import repair, extensions, url, error
-import os, sys, re, errno, shutil
-
-commands.norepo += " qclone"
-
-# Patch names looks like unix-file names.
-# They must be joinable with queue directory and result in the patch path.
-normname = util.normpath
-
-class statusentry(object):
- def __init__(self, node, name):
- self.node, self.name = node, name
- def __repr__(self):
- return hex(self.node) + ':' + self.name
-
-class patchheader(object):
- def __init__(self, pf, plainmode=False):
- def eatdiff(lines):
- while lines:
- l = lines[-1]
- if (l.startswith("diff -") or
- l.startswith("Index:") or
- l.startswith("===========")):
- del lines[-1]
- else:
- break
- def eatempty(lines):
- while lines:
- if not lines[-1].strip():
- del lines[-1]
- else:
- break
-
- message = []
- comments = []
- user = None
- date = None
- parent = None
- format = None
- subject = None
- diffstart = 0
-
- for line in file(pf):
- line = line.rstrip()
- if (line.startswith('diff --git')
- or (diffstart and line.startswith('+++ '))):
- diffstart = 2
- break
- diffstart = 0 # reset
- if line.startswith("--- "):
- diffstart = 1
- continue
- elif format == "hgpatch":
- # parse values when importing the result of an hg export
- if line.startswith("# User "):
- user = line[7:]
- elif line.startswith("# Date "):
- date = line[7:]
- elif line.startswith("# Parent "):
- parent = line[9:]
- elif not line.startswith("# ") and line:
- message.append(line)
- format = None
- elif line == '# HG changeset patch':
- message = []
- format = "hgpatch"
- elif (format != "tagdone" and (line.startswith("Subject: ") or
- line.startswith("subject: "))):
- subject = line[9:]
- format = "tag"
- elif (format != "tagdone" and (line.startswith("From: ") or
- line.startswith("from: "))):
- user = line[6:]
- format = "tag"
- elif (format != "tagdone" and (line.startswith("Date: ") or
- line.startswith("date: "))):
- date = line[6:]
- format = "tag"
- elif format == "tag" and line == "":
- # when looking for tags (subject: from: etc) they
- # end once you find a blank line in the source
- format = "tagdone"
- elif message or line:
- message.append(line)
- comments.append(line)
-
- eatdiff(message)
- eatdiff(comments)
- eatempty(message)
- eatempty(comments)
-
- # make sure message isn't empty
- if format and format.startswith("tag") and subject:
- message.insert(0, "")
- message.insert(0, subject)
-
- self.message = message
- self.comments = comments
- self.user = user
- self.date = date
- self.parent = parent
- self.haspatch = diffstart > 1
- self.plainmode = plainmode
-
- def setuser(self, user):
- if not self.updateheader(['From: ', '# User '], user):
- try:
- patchheaderat = self.comments.index('# HG changeset patch')
- self.comments.insert(patchheaderat + 1, '# User ' + user)
- except ValueError:
- if self.plainmode or self._hasheader(['Date: ']):
- self.comments = ['From: ' + user] + self.comments
- else:
- tmp = ['# HG changeset patch', '# User ' + user, '']
- self.comments = tmp + self.comments
- self.user = user
-
- def setdate(self, date):
- if not self.updateheader(['Date: ', '# Date '], date):
- try:
- patchheaderat = self.comments.index('# HG changeset patch')
- self.comments.insert(patchheaderat + 1, '# Date ' + date)
- except ValueError:
- if self.plainmode or self._hasheader(['From: ']):
- self.comments = ['Date: ' + date] + self.comments
- else:
- tmp = ['# HG changeset patch', '# Date ' + date, '']
- self.comments = tmp + self.comments
- self.date = date
-
- def setparent(self, parent):
- if not self.updateheader(['# Parent '], parent):
- try:
- patchheaderat = self.comments.index('# HG changeset patch')
- self.comments.insert(patchheaderat + 1, '# Parent ' + parent)
- except ValueError:
- pass
- self.parent = parent
-
- def setmessage(self, message):
- if self.comments:
- self._delmsg()
- self.message = [message]
- self.comments += self.message
-
- def updateheader(self, prefixes, new):
- '''Update all references to a field in the patch header.
- Return whether the field is present.'''
- res = False
- for prefix in prefixes:
- for i in xrange(len(self.comments)):
- if self.comments[i].startswith(prefix):
- self.comments[i] = prefix + new
- res = True
- break
- return res
-
- def _hasheader(self, prefixes):
- '''Check if a header starts with any of the given prefixes.'''
- for prefix in prefixes:
- for comment in self.comments:
- if comment.startswith(prefix):
- return True
- return False
-
- def __str__(self):
- if not self.comments:
- return ''
- return '\n'.join(self.comments) + '\n\n'
-
- def _delmsg(self):
- '''Remove existing message, keeping the rest of the comments fields.
- If comments contains 'subject: ', message will prepend
- the field and a blank line.'''
- if self.message:
- subj = 'subject: ' + self.message[0].lower()
- for i in xrange(len(self.comments)):
- if subj == self.comments[i].lower():
- del self.comments[i]
- self.message = self.message[2:]
- break
- ci = 0
- for mi in self.message:
- while mi != self.comments[ci]:
- ci += 1
- del self.comments[ci]
-
-class queue(object):
- def __init__(self, ui, path, patchdir=None):
- self.basepath = path
- try:
- fh = open(os.path.join(path, 'patches.queue'))
- cur = fh.read().rstrip()
- if not cur:
- curpath = os.path.join(path, 'patches')
- else:
- curpath = os.path.join(path, 'patches-' + cur)
- except IOError:
- curpath = os.path.join(path, 'patches')
- self.path = patchdir or curpath
- self.opener = util.opener(self.path)
- self.ui = ui
- self.applied_dirty = 0
- self.series_dirty = 0
- self.added = []
- self.series_path = "series"
- self.status_path = "status"
- self.guards_path = "guards"
- self.active_guards = None
- self.guards_dirty = False
- # Handle mq.git as a bool with extended values
- try:
- gitmode = ui.configbool('mq', 'git', None)
- if gitmode is None:
- raise error.ConfigError()
- self.gitmode = gitmode and 'yes' or 'no'
- except error.ConfigError:
- self.gitmode = ui.config('mq', 'git', 'auto').lower()
- self.plainmode = ui.configbool('mq', 'plain', False)
-
- @util.propertycache
- def applied(self):
- if os.path.exists(self.join(self.status_path)):
- def parse(l):
- n, name = l.split(':', 1)
- return statusentry(bin(n), name)
- lines = self.opener(self.status_path).read().splitlines()
- return [parse(l) for l in lines]
- return []
-
- @util.propertycache
- def full_series(self):
- if os.path.exists(self.join(self.series_path)):
- return self.opener(self.series_path).read().splitlines()
- return []
-
- @util.propertycache
- def series(self):
- self.parse_series()
- return self.series
-
- @util.propertycache
- def series_guards(self):
- self.parse_series()
- return self.series_guards
-
- def invalidate(self):
- for a in 'applied full_series series series_guards'.split():
- if a in self.__dict__:
- delattr(self, a)
- self.applied_dirty = 0
- self.series_dirty = 0
- self.guards_dirty = False
- self.active_guards = None
-
- def diffopts(self, opts={}, patchfn=None):
- diffopts = patch.diffopts(self.ui, opts)
- if self.gitmode == 'auto':
- diffopts.upgrade = True
- elif self.gitmode == 'keep':
- pass
- elif self.gitmode in ('yes', 'no'):
- diffopts.git = self.gitmode == 'yes'
- else:
- raise util.Abort(_('mq.git option can be auto/keep/yes/no'
- ' got %s') % self.gitmode)
- if patchfn:
- diffopts = self.patchopts(diffopts, patchfn)
- return diffopts
-
- def patchopts(self, diffopts, *patches):
- """Return a copy of input diff options with git set to true if
- referenced patch is a git patch and should be preserved as such.
- """
- diffopts = diffopts.copy()
- if not diffopts.git and self.gitmode == 'keep':
- for patchfn in patches:
- patchf = self.opener(patchfn, 'r')
- # if the patch was a git patch, refresh it as a git patch
- for line in patchf:
- if line.startswith('diff --git'):
- diffopts.git = True
- break
- patchf.close()
- return diffopts
-
- def join(self, *p):
- return os.path.join(self.path, *p)
-
- def find_series(self, patch):
- def matchpatch(l):
- l = l.split('#', 1)[0]
- return l.strip() == patch
- for index, l in enumerate(self.full_series):
- if matchpatch(l):
- return index
- return None
-
- guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
-
- def parse_series(self):
- self.series = []
- self.series_guards = []
- for l in self.full_series:
- h = l.find('#')
- if h == -1:
- patch = l
- comment = ''
- elif h == 0:
- continue
- else:
- patch = l[:h]
- comment = l[h:]
- patch = patch.strip()
- if patch:
- if patch in self.series:
- raise util.Abort(_('%s appears more than once in %s') %
- (patch, self.join(self.series_path)))
- self.series.append(patch)
- self.series_guards.append(self.guard_re.findall(comment))
-
- def check_guard(self, guard):
- if not guard:
- return _('guard cannot be an empty string')
- bad_chars = '# \t\r\n\f'
- first = guard[0]
- if first in '-+':
- return (_('guard %r starts with invalid character: %r') %
- (guard, first))
- for c in bad_chars:
- if c in guard:
- return _('invalid character in guard %r: %r') % (guard, c)
-
- def set_active(self, guards):
- for guard in guards:
- bad = self.check_guard(guard)
- if bad:
- raise util.Abort(bad)
- guards = sorted(set(guards))
- self.ui.debug('active guards: %s\n' % ' '.join(guards))
- self.active_guards = guards
- self.guards_dirty = True
-
- def active(self):
- if self.active_guards is None:
- self.active_guards = []
- try:
- guards = self.opener(self.guards_path).read().split()
- except IOError, err:
- if err.errno != errno.ENOENT:
- raise
- guards = []
- for i, guard in enumerate(guards):
- bad = self.check_guard(guard)
- if bad:
- self.ui.warn('%s:%d: %s\n' %
- (self.join(self.guards_path), i + 1, bad))
- else:
- self.active_guards.append(guard)
- return self.active_guards
-
- def set_guards(self, idx, guards):
- for g in guards:
- if len(g) < 2:
- raise util.Abort(_('guard %r too short') % g)
- if g[0] not in '-+':
- raise util.Abort(_('guard %r starts with invalid char') % g)
- bad = self.check_guard(g[1:])
- if bad:
- raise util.Abort(bad)
- drop = self.guard_re.sub('', self.full_series[idx])
- self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
- self.parse_series()
- self.series_dirty = True
-
- def pushable(self, idx):
- if isinstance(idx, str):
- idx = self.series.index(idx)
- patchguards = self.series_guards[idx]
- if not patchguards:
- return True, None
- guards = self.active()
- exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
- if exactneg:
- return False, exactneg[0]
- pos = [g for g in patchguards if g[0] == '+']
- exactpos = [g for g in pos if g[1:] in guards]
- if pos:
- if exactpos:
- return True, exactpos[0]
- return False, pos
- return True, ''
-
- def explain_pushable(self, idx, all_patches=False):
- write = all_patches and self.ui.write or self.ui.warn
- if all_patches or self.ui.verbose:
- if isinstance(idx, str):
- idx = self.series.index(idx)
- pushable, why = self.pushable(idx)
- if all_patches and pushable:
- if why is None:
- write(_('allowing %s - no guards in effect\n') %
- self.series[idx])
- else:
- if not why:
- write(_('allowing %s - no matching negative guards\n') %
- self.series[idx])
- else:
- write(_('allowing %s - guarded by %r\n') %
- (self.series[idx], why))
- if not pushable:
- if why:
- write(_('skipping %s - guarded by %r\n') %
- (self.series[idx], why))
- else:
- write(_('skipping %s - no matching guards\n') %
- self.series[idx])
-
- def save_dirty(self):
- def write_list(items, path):
- fp = self.opener(path, 'w')
- for i in items:
- fp.write("%s\n" % i)
- fp.close()
- if self.applied_dirty:
- write_list(map(str, self.applied), self.status_path)
- if self.series_dirty:
- write_list(self.full_series, self.series_path)
- if self.guards_dirty:
- write_list(self.active_guards, self.guards_path)
- if self.added:
- qrepo = self.qrepo()
- if qrepo:
- qrepo[None].add(f for f in self.added if f not in qrepo[None])
- self.added = []
-
- def removeundo(self, repo):
- undo = repo.sjoin('undo')
- if not os.path.exists(undo):
- return
- try:
- os.unlink(undo)
- except OSError, inst:
- self.ui.warn(_('error removing undo: %s\n') % str(inst))
-
- def printdiff(self, repo, diffopts, node1, node2=None, files=None,
- fp=None, changes=None, opts={}):
- stat = opts.get('stat')
- m = cmdutil.match(repo, files, opts)
- cmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2, m,
- changes, stat, fp)
-
- def mergeone(self, repo, mergeq, head, patch, rev, diffopts):
- # first try just applying the patch
- (err, n) = self.apply(repo, [patch], update_status=False,
- strict=True, merge=rev)
-
- if err == 0:
- return (err, n)
-
- if n is None:
- raise util.Abort(_("apply failed for patch %s") % patch)
-
- self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
-
- # apply failed, strip away that rev and merge.
- hg.clean(repo, head)
- self.strip(repo, [n], update=False, backup='strip')
-
- ctx = repo[rev]
- ret = hg.merge(repo, rev)
- if ret:
- raise util.Abort(_("update returned %d") % ret)
- n = repo.commit(ctx.description(), ctx.user(), force=True)
- if n is None:
- raise util.Abort(_("repo commit failed"))
- try:
- ph = patchheader(mergeq.join(patch), self.plainmode)
- except:
- raise util.Abort(_("unable to read %s") % patch)
-
- diffopts = self.patchopts(diffopts, patch)
- patchf = self.opener(patch, "w")
- comments = str(ph)
- if comments:
- patchf.write(comments)
- self.printdiff(repo, diffopts, head, n, fp=patchf)
- patchf.close()
- self.removeundo(repo)
- return (0, n)
-
- def qparents(self, repo, rev=None):
- if rev is None:
- (p1, p2) = repo.dirstate.parents()
- if p2 == nullid:
- return p1
- if not self.applied:
- return None
- return self.applied[-1].node
- p1, p2 = repo.changelog.parents(rev)
- if p2 != nullid and p2 in [x.node for x in self.applied]:
- return p2
- return p1
-
- def mergepatch(self, repo, mergeq, series, diffopts):
- if not self.applied:
- # each of the patches merged in will have two parents. This
- # can confuse the qrefresh, qdiff, and strip code because it
- # needs to know which parent is actually in the patch queue.
- # so, we insert a merge marker with only one parent. This way
- # the first patch in the queue is never a merge patch
- #
- pname = ".hg.patches.merge.marker"
- n = repo.commit('[mq]: merge marker', force=True)
- self.removeundo(repo)
- self.applied.append(statusentry(n, pname))
- self.applied_dirty = 1
-
- head = self.qparents(repo)
-
- for patch in series:
- patch = mergeq.lookup(patch, strict=True)
- if not patch:
- self.ui.warn(_("patch %s does not exist\n") % patch)
- return (1, None)
- pushable, reason = self.pushable(patch)
- if not pushable:
- self.explain_pushable(patch, all_patches=True)
- continue
- info = mergeq.isapplied(patch)
- if not info:
- self.ui.warn(_("patch %s is not applied\n") % patch)
- return (1, None)
- rev = info[1]
- err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts)
- if head:
- self.applied.append(statusentry(head, patch))
- self.applied_dirty = 1
- if err:
- return (err, head)
- self.save_dirty()
- return (0, head)
-
- def patch(self, repo, patchfile):
- '''Apply patchfile to the working directory.
- patchfile: name of patch file'''
- files = {}
- try:
- fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root,
- files=files, eolmode=None)
- except Exception, inst:
- self.ui.note(str(inst) + '\n')
- if not self.ui.verbose:
- self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
- return (False, files, False)
-
- return (True, files, fuzz)
-
- def apply(self, repo, series, list=False, update_status=True,
- strict=False, patchdir=None, merge=None, all_files=None):
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- tr = repo.transaction("qpush")
- try:
- ret = self._apply(repo, series, list, update_status,
- strict, patchdir, merge, all_files=all_files)
- tr.close()
- self.save_dirty()
- return ret
- except:
- try:
- tr.abort()
- finally:
- repo.invalidate()
- repo.dirstate.invalidate()
- raise
- finally:
- release(tr, lock, wlock)
- self.removeundo(repo)
-
- def _apply(self, repo, series, list=False, update_status=True,
- strict=False, patchdir=None, merge=None, all_files=None):
- '''returns (error, hash)
- error = 1 for unable to read, 2 for patch failed, 3 for patch fuzz'''
- # TODO unify with commands.py
- if not patchdir:
- patchdir = self.path
- err = 0
- n = None
- for patchname in series:
- pushable, reason = self.pushable(patchname)
- if not pushable:
- self.explain_pushable(patchname, all_patches=True)
- continue
- self.ui.status(_("applying %s\n") % patchname)
- pf = os.path.join(patchdir, patchname)
-
- try:
- ph = patchheader(self.join(patchname), self.plainmode)
- except:
- self.ui.warn(_("unable to read %s\n") % patchname)
- err = 1
- break
-
- message = ph.message
- if not message:
- # The commit message should not be translated
- message = "imported patch %s\n" % patchname
- else:
- if list:
- # The commit message should not be translated
- message.append("\nimported patch %s" % patchname)
- message = '\n'.join(message)
-
- if ph.haspatch:
- (patcherr, files, fuzz) = self.patch(repo, pf)
- if all_files is not None:
- all_files.update(files)
- patcherr = not patcherr
- else:
- self.ui.warn(_("patch %s is empty\n") % patchname)
- patcherr, files, fuzz = 0, [], 0
-
- if merge and files:
- # Mark as removed/merged and update dirstate parent info
- removed = []
- merged = []
- for f in files:
- if os.path.lexists(repo.wjoin(f)):
- merged.append(f)
- else:
- removed.append(f)
- for f in removed:
- repo.dirstate.remove(f)
- for f in merged:
- repo.dirstate.merge(f)
- p1, p2 = repo.dirstate.parents()
- repo.dirstate.setparents(p1, merge)
-
- files = cmdutil.updatedir(self.ui, repo, files)
- match = cmdutil.matchfiles(repo, files or [])
- n = repo.commit(message, ph.user, ph.date, match=match, force=True)
-
- if n is None:
- raise util.Abort(_("repository commit failed"))
-
- if update_status:
- self.applied.append(statusentry(n, patchname))
-
- if patcherr:
- self.ui.warn(_("patch failed, rejects left in working dir\n"))
- err = 2
- break
-
- if fuzz and strict:
- self.ui.warn(_("fuzz found when applying patch, stopping\n"))
- err = 3
- break
- return (err, n)
-
- def _cleanup(self, patches, numrevs, keep=False):
- if not keep:
- r = self.qrepo()
- if r:
- r[None].remove(patches, True)
- else:
- for p in patches:
- os.unlink(self.join(p))
-
- if numrevs:
- del self.applied[:numrevs]
- self.applied_dirty = 1
-
- for i in sorted([self.find_series(p) for p in patches], reverse=True):
- del self.full_series[i]
- self.parse_series()
- self.series_dirty = 1
-
- def _revpatches(self, repo, revs):
- firstrev = repo[self.applied[0].node].rev()
- patches = []
- for i, rev in enumerate(revs):
-
- if rev < firstrev:
- raise util.Abort(_('revision %d is not managed') % rev)
-
- ctx = repo[rev]
- base = self.applied[i].node
- if ctx.node() != base:
- msg = _('cannot delete revision %d above applied patches')
- raise util.Abort(msg % rev)
-
- patch = self.applied[i].name
- for fmt in ('[mq]: %s', 'imported patch %s'):
- if ctx.description() == fmt % patch:
- msg = _('patch %s finalized without changeset message\n')
- repo.ui.status(msg % patch)
- break
-
- patches.append(patch)
- return patches
-
- def finish(self, repo, revs):
- patches = self._revpatches(repo, sorted(revs))
- self._cleanup(patches, len(patches))
-
- def delete(self, repo, patches, opts):
- if not patches and not opts.get('rev'):
- raise util.Abort(_('qdelete requires at least one revision or '
- 'patch name'))
-
- realpatches = []
- for patch in patches:
- patch = self.lookup(patch, strict=True)
- info = self.isapplied(patch)
- if info:
- raise util.Abort(_("cannot delete applied patch %s") % patch)
- if patch not in self.series:
- raise util.Abort(_("patch %s not in series file") % patch)
- if patch not in realpatches:
- realpatches.append(patch)
-
- numrevs = 0
- if opts.get('rev'):
- if not self.applied:
- raise util.Abort(_('no patches applied'))
- revs = cmdutil.revrange(repo, opts.get('rev'))
- if len(revs) > 1 and revs[0] > revs[1]:
- revs.reverse()
- revpatches = self._revpatches(repo, revs)
- realpatches += revpatches
- numrevs = len(revpatches)
-
- self._cleanup(realpatches, numrevs, opts.get('keep'))
-
- def check_toppatch(self, repo):
- if self.applied:
- top = self.applied[-1].node
- patch = self.applied[-1].name
- pp = repo.dirstate.parents()
- if top not in pp:
- raise util.Abort(_("working directory revision is not qtip"))
- return top, patch
- return None, None
-
- def check_localchanges(self, repo, force=False, refresh=True):
- m, a, r, d = repo.status()[:4]
- if (m or a or r or d) and not force:
- if refresh:
- raise util.Abort(_("local changes found, refresh first"))
- else:
- raise util.Abort(_("local changes found"))
- return m, a, r, d
-
- _reserved = ('series', 'status', 'guards')
- def check_reserved_name(self, name):
- if (name in self._reserved or name.startswith('.hg')
- or name.startswith('.mq') or '#' in name or ':' in name):
- raise util.Abort(_('"%s" cannot be used as the name of a patch')
- % name)
-
- def new(self, repo, patchfn, *pats, **opts):
- """options:
- msg: a string or a no-argument function returning a string
- """
- msg = opts.get('msg')
- user = opts.get('user')
- date = opts.get('date')
- if date:
- date = util.parsedate(date)
- diffopts = self.diffopts({'git': opts.get('git')})
- self.check_reserved_name(patchfn)
- if os.path.exists(self.join(patchfn)):
- if os.path.isdir(self.join(patchfn)):
- raise util.Abort(_('"%s" already exists as a directory')
- % patchfn)
- else:
- raise util.Abort(_('patch "%s" already exists') % patchfn)
- if opts.get('include') or opts.get('exclude') or pats:
- match = cmdutil.match(repo, pats, opts)
- # detect missing files in pats
- def badfn(f, msg):
- raise util.Abort('%s: %s' % (f, msg))
- match.bad = badfn
- m, a, r, d = repo.status(match=match)[:4]
- else:
- m, a, r, d = self.check_localchanges(repo, force=True)
- match = cmdutil.matchfiles(repo, m + a + r)
- if len(repo[None].parents()) > 1:
- raise util.Abort(_('cannot manage merge changesets'))
- commitfiles = m + a + r
- self.check_toppatch(repo)
- insert = self.full_series_end()
- wlock = repo.wlock()
- try:
- try:
- # if patch file write fails, abort early
- p = self.opener(patchfn, "w")
- except IOError, e:
- raise util.Abort(_('cannot write patch "%s": %s')
- % (patchfn, e.strerror))
- try:
- if self.plainmode:
- if user:
- p.write("From: " + user + "\n")
- if not date:
- p.write("\n")
- if date:
- p.write("Date: %d %d\n\n" % date)
- else:
- p.write("# HG changeset patch\n")
- p.write("# Parent "
- + hex(repo[None].parents()[0].node()) + "\n")
- if user:
- p.write("# User " + user + "\n")
- if date:
- p.write("# Date %s %s\n\n" % date)
- if hasattr(msg, '__call__'):
- msg = msg()
- commitmsg = msg and msg or ("[mq]: %s" % patchfn)
- n = repo.commit(commitmsg, user, date, match=match, force=True)
- if n is None:
- raise util.Abort(_("repo commit failed"))
- try:
- self.full_series[insert:insert] = [patchfn]
- self.applied.append(statusentry(n, patchfn))
- self.parse_series()
- self.series_dirty = 1
- self.applied_dirty = 1
- if msg:
- msg = msg + "\n\n"
- p.write(msg)
- if commitfiles:
- parent = self.qparents(repo, n)
- chunks = patch.diff(repo, node1=parent, node2=n,
- match=match, opts=diffopts)
- for chunk in chunks:
- p.write(chunk)
- p.close()
- wlock.release()
- wlock = None
- r = self.qrepo()
- if r:
- r[None].add([patchfn])
- except:
- repo.rollback()
- raise
- except Exception:
- patchpath = self.join(patchfn)
- try:
- os.unlink(patchpath)
- except:
- self.ui.warn(_('error unlinking %s\n') % patchpath)
- raise
- self.removeundo(repo)
- finally:
- release(wlock)
-
- def strip(self, repo, revs, update=True, backup="all", force=None):
- wlock = lock = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
-
- if update:
- self.check_localchanges(repo, force=force, refresh=False)
- urev = self.qparents(repo, revs[0])
- hg.clean(repo, urev)
- repo.dirstate.write()
-
- self.removeundo(repo)
- for rev in revs:
- repair.strip(self.ui, repo, rev, backup)
- # strip may have unbundled a set of backed up revisions after
- # the actual strip
- self.removeundo(repo)
- finally:
- release(lock, wlock)
-
- def isapplied(self, patch):
- """returns (index, rev, patch)"""
- for i, a in enumerate(self.applied):
- if a.name == patch:
- return (i, a.node, a.name)
- return None
-
- # if the exact patch name does not exist, we try a few
- # variations. If strict is passed, we try only #1
- #
- # 1) a number to indicate an offset in the series file
- # 2) a unique substring of the patch name was given
- # 3) patchname[-+]num to indicate an offset in the series file
- def lookup(self, patch, strict=False):
- patch = patch and str(patch)
-
- def partial_name(s):
- if s in self.series:
- return s
- matches = [x for x in self.series if s in x]
- if len(matches) > 1:
- self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
- for m in matches:
- self.ui.warn(' %s\n' % m)
- return None
- if matches:
- return matches[0]
- if self.series and self.applied:
- if s == 'qtip':
- return self.series[self.series_end(True)-1]
- if s == 'qbase':
- return self.series[0]
- return None
-
- if patch is None:
- return None
- if patch in self.series:
- return patch
-
- if not os.path.isfile(self.join(patch)):
- try:
- sno = int(patch)
- except (ValueError, OverflowError):
- pass
- else:
- if -len(self.series) <= sno < len(self.series):
- return self.series[sno]
-
- if not strict:
- res = partial_name(patch)
- if res:
- return res
- minus = patch.rfind('-')
- if minus >= 0:
- res = partial_name(patch[:minus])
- if res:
- i = self.series.index(res)
- try:
- off = int(patch[minus + 1:] or 1)
- except (ValueError, OverflowError):
- pass
- else:
- if i - off >= 0:
- return self.series[i - off]
- plus = patch.rfind('+')
- if plus >= 0:
- res = partial_name(patch[:plus])
- if res:
- i = self.series.index(res)
- try:
- off = int(patch[plus + 1:] or 1)
- except (ValueError, OverflowError):
- pass
- else:
- if i + off < len(self.series):
- return self.series[i + off]
- raise util.Abort(_("patch %s not in series") % patch)
-
- def push(self, repo, patch=None, force=False, list=False,
- mergeq=None, all=False, move=False):
- diffopts = self.diffopts()
- wlock = repo.wlock()
- try:
- heads = []
- for b, ls in repo.branchmap().iteritems():
- heads += ls
- if not heads:
- heads = [nullid]
- if repo.dirstate.parents()[0] not in heads:
- self.ui.status(_("(working directory not at a head)\n"))
-
- if not self.series:
- self.ui.warn(_('no patches in series\n'))
- return 0
-
- patch = self.lookup(patch)
- # Suppose our series file is: A B C and the current 'top'
- # patch is B. qpush C should be performed (moving forward)
- # qpush B is a NOP (no change) qpush A is an error (can't
- # go backwards with qpush)
- if patch:
- info = self.isapplied(patch)
- if info:
- if info[0] < len(self.applied) - 1:
- raise util.Abort(
- _("cannot push to a previous patch: %s") % patch)
- self.ui.warn(
- _('qpush: %s is already at the top\n') % patch)
- return 0
- pushable, reason = self.pushable(patch)
- if not pushable:
- if reason:
- reason = _('guarded by %r') % reason
- else:
- reason = _('no matching guards')
- self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
- return 1
- elif all:
- patch = self.series[-1]
- if self.isapplied(patch):
- self.ui.warn(_('all patches are currently applied\n'))
- return 0
-
- # Following the above example, starting at 'top' of B:
- # qpush should be performed (pushes C), but a subsequent
- # qpush without an argument is an error (nothing to
- # apply). This allows a loop of "...while hg qpush..." to
- # work as it detects an error when done
- start = self.series_end()
- if start == len(self.series):
- self.ui.warn(_('patch series already fully applied\n'))
- return 1
- if not force:
- self.check_localchanges(repo)
-
- if move:
- if not patch:
- raise util.Abort(_("please specify the patch to move"))
- for i, rpn in enumerate(self.full_series[start:]):
- # strip markers for patch guards
- if self.guard_re.split(rpn, 1)[0] == patch:
- break
- index = start + i
- assert index < len(self.full_series)
- fullpatch = self.full_series[index]
- del self.full_series[index]
- self.full_series.insert(start, fullpatch)
- self.parse_series()
- self.series_dirty = 1
-
- self.applied_dirty = 1
- if start > 0:
- self.check_toppatch(repo)
- if not patch:
- patch = self.series[start]
- end = start + 1
- else:
- end = self.series.index(patch, start) + 1
-
- s = self.series[start:end]
- all_files = set()
- try:
- if mergeq:
- ret = self.mergepatch(repo, mergeq, s, diffopts)
- else:
- ret = self.apply(repo, s, list, all_files=all_files)
- except:
- self.ui.warn(_('cleaning up working directory...'))
- node = repo.dirstate.parents()[0]
- hg.revert(repo, node, None)
- # only remove unknown files that we know we touched or
- # created while patching
- for f in all_files:
- if f not in repo.dirstate:
- try:
- util.unlink(repo.wjoin(f))
- except OSError, inst:
- if inst.errno != errno.ENOENT:
- raise
- self.ui.warn(_('done\n'))
- raise
-
- if not self.applied:
- return ret[0]
- top = self.applied[-1].name
- if ret[0] and ret[0] > 1:
- msg = _("errors during apply, please fix and refresh %s\n")
- self.ui.write(msg % top)
- else:
- self.ui.write(_("now at: %s\n") % top)
- return ret[0]
-
- finally:
- wlock.release()
-
- def pop(self, repo, patch=None, force=False, update=True, all=False):
- wlock = repo.wlock()
- try:
- if patch:
- # index, rev, patch
- info = self.isapplied(patch)
- if not info:
- patch = self.lookup(patch)
- info = self.isapplied(patch)
- if not info:
- raise util.Abort(_("patch %s is not applied") % patch)
-
- if not self.applied:
- # Allow qpop -a to work repeatedly,
- # but not qpop without an argument
- self.ui.warn(_("no patches applied\n"))
- return not all
-
- if all:
- start = 0
- elif patch:
- start = info[0] + 1
- else:
- start = len(self.applied) - 1
-
- if start >= len(self.applied):
- self.ui.warn(_("qpop: %s is already at the top\n") % patch)
- return
-
- if not update:
- parents = repo.dirstate.parents()
- rr = [x.node for x in self.applied]
- for p in parents:
- if p in rr:
- self.ui.warn(_("qpop: forcing dirstate update\n"))
- update = True
- else:
- parents = [p.node() for p in repo[None].parents()]
- needupdate = False
- for entry in self.applied[start:]:
- if entry.node in parents:
- needupdate = True
- break
- update = needupdate
-
- if not force and update:
- self.check_localchanges(repo)
-
- self.applied_dirty = 1
- end = len(self.applied)
- rev = self.applied[start].node
- if update:
- top = self.check_toppatch(repo)[0]
-
- try:
- heads = repo.changelog.heads(rev)
- except error.LookupError:
- node = short(rev)
- raise util.Abort(_('trying to pop unknown node %s') % node)
-
- if heads != [self.applied[-1].node]:
- raise util.Abort(_("popping would remove a revision not "
- "managed by this patch queue"))
-
- # we know there are no local changes, so we can make a simplified
- # form of hg.update.
- if update:
- qp = self.qparents(repo, rev)
- ctx = repo[qp]
- m, a, r, d = repo.status(qp, top)[:4]
- if d:
- raise util.Abort(_("deletions found between repo revs"))
- for f in a:
- try:
- util.unlink(repo.wjoin(f))
- except OSError, e:
- if e.errno != errno.ENOENT:
- raise
- repo.dirstate.forget(f)
- for f in m + r:
- fctx = ctx[f]
- repo.wwrite(f, fctx.data(), fctx.flags())
- repo.dirstate.normal(f)
- repo.dirstate.setparents(qp, nullid)
- for patch in reversed(self.applied[start:end]):
- self.ui.status(_("popping %s\n") % patch.name)
- del self.applied[start:end]
- self.strip(repo, [rev], update=False, backup='strip')
- if self.applied:
- self.ui.write(_("now at: %s\n") % self.applied[-1].name)
- else:
- self.ui.write(_("patch queue now empty\n"))
- finally:
- wlock.release()
-
- def diff(self, repo, pats, opts):
- top, patch = self.check_toppatch(repo)
- if not top:
- self.ui.write(_("no patches applied\n"))
- return
- qp = self.qparents(repo, top)
- if opts.get('reverse'):
- node1, node2 = None, qp
- else:
- node1, node2 = qp, None
- diffopts = self.diffopts(opts, patch)
- self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts)
-
- def refresh(self, repo, pats=None, **opts):
- if not self.applied:
- self.ui.write(_("no patches applied\n"))
- return 1
- msg = opts.get('msg', '').rstrip()
- newuser = opts.get('user')
- newdate = opts.get('date')
- if newdate:
- newdate = '%d %d' % util.parsedate(newdate)
- wlock = repo.wlock()
-
- try:
- self.check_toppatch(repo)
- (top, patchfn) = (self.applied[-1].node, self.applied[-1].name)
- if repo.changelog.heads(top) != [top]:
- raise util.Abort(_("cannot refresh a revision with children"))
-
- cparents = repo.changelog.parents(top)
- patchparent = self.qparents(repo, top)
- ph = patchheader(self.join(patchfn), self.plainmode)
- diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
- if msg:
- ph.setmessage(msg)
- if newuser:
- ph.setuser(newuser)
- if newdate:
- ph.setdate(newdate)
- ph.setparent(hex(patchparent))
-
- # only commit new patch when write is complete
- patchf = self.opener(patchfn, 'w', atomictemp=True)
-
- comments = str(ph)
- if comments:
- patchf.write(comments)
-
- # update the dirstate in place, strip off the qtip commit
- # and then commit.
- #
- # this should really read:
- # 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 = repo.status(patchparent, top)[:4]
- changes = repo.changelog.read(top)
- man = repo.manifest.read(changes[0])
- aaa = aa[:]
- matchfn = cmdutil.match(repo, pats, opts)
- # in short mode, we only diff the files included in the
- # patch already plus specified files
- if opts.get('short'):
- # if amending a patch, we start with existing
- # files plus specified files - unfiltered
- match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
- # filter with inc/exl options
- matchfn = cmdutil.match(repo, opts=opts)
- else:
- match = cmdutil.matchall(repo)
- m, a, r, d = repo.status(match=match)[:4]
-
- # we might end up with files that were added between
- # qtip and the dirstate parent, but then changed in the
- # local dirstate. in this case, we want them to only
- # show up in the added section
- for x in m:
- if x == '.hgsub' or x == '.hgsubstate':
- self.ui.warn(_('warning: not refreshing %s\n') % x)
- continue
- if x not in aa:
- mm.append(x)
- # we might end up with files added by the local dirstate that
- # were deleted by the patch. In this case, they should only
- # show up in the changed section.
- for x in a:
- if x == '.hgsub' or x == '.hgsubstate':
- self.ui.warn(_('warning: not adding %s\n') % x)
- continue
- if x in dd:
- del dd[dd.index(x)]
- mm.append(x)
- else:
- aa.append(x)
- # make sure any files deleted in the local dirstate
- # are not in the add or change column of the patch
- forget = []
- for x in d + r:
- if x == '.hgsub' or x == '.hgsubstate':
- self.ui.warn(_('warning: not removing %s\n') % x)
- continue
- if x in aa:
- del aa[aa.index(x)]
- forget.append(x)
- continue
- elif x in mm:
- del mm[mm.index(x)]
- dd.append(x)
-
- m = list(set(mm))
- r = list(set(dd))
- a = list(set(aa))
- c = [filter(matchfn, l) for l in (m, a, r)]
- match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
- chunks = patch.diff(repo, patchparent, match=match,
- changes=c, opts=diffopts)
- for chunk in chunks:
- patchf.write(chunk)
-
- try:
- if diffopts.git or diffopts.upgrade:
- copies = {}
- for dst in a:
- src = repo.dirstate.copied(dst)
- # during qfold, the source file for copies may
- # be removed. Treat this as a simple add.
- if src is not None and src in repo.dirstate:
- copies.setdefault(src, []).append(dst)
- repo.dirstate.add(dst)
- # remember the copies between patchparent and qtip
- for dst in aaa:
- f = repo.file(dst)
- src = f.renamed(man[dst])
- if src:
- copies.setdefault(src[0], []).extend(
- copies.get(dst, []))
- if dst in a:
- copies[src[0]].append(dst)
- # we can't copy a file created by the patch itself
- if dst in copies:
- del copies[dst]
- for src, dsts in copies.iteritems():
- for dst in dsts:
- repo.dirstate.copy(src, dst)
- else:
- for dst in a:
- repo.dirstate.add(dst)
- # Drop useless copy information
- for f in list(repo.dirstate.copies()):
- repo.dirstate.copy(None, f)
- for f in r:
- repo.dirstate.remove(f)
- # if the patch excludes a modified file, mark that
- # file with mtime=0 so status can see it.
- mm = []
- for i in xrange(len(m)-1, -1, -1):
- if not matchfn(m[i]):
- mm.append(m[i])
- del m[i]
- for f in m:
- repo.dirstate.normal(f)
- for f in mm:
- repo.dirstate.normallookup(f)
- for f in forget:
- repo.dirstate.forget(f)
-
- if not msg:
- if not ph.message:
- message = "[mq]: %s\n" % patchfn
- else:
- message = "\n".join(ph.message)
- else:
- message = msg
-
- user = ph.user or changes[1]
-
- # assumes strip can roll itself back if interrupted
- repo.dirstate.setparents(*cparents)
- self.applied.pop()
- self.applied_dirty = 1
- self.strip(repo, [top], update=False,
- backup='strip')
- except:
- repo.dirstate.invalidate()
- raise
-
- try:
- # might be nice to attempt to roll back strip after this
- patchf.rename()
- n = repo.commit(message, user, ph.date, match=match,
- force=True)
- self.applied.append(statusentry(n, patchfn))
- except:
- ctx = repo[cparents[0]]
- repo.dirstate.rebuild(ctx.node(), ctx.manifest())
- self.save_dirty()
- self.ui.warn(_('refresh interrupted while patch was popped! '
- '(revert --all, qpush to recover)\n'))
- raise
- finally:
- wlock.release()
- self.removeundo(repo)
-
- def init(self, repo, create=False):
- if not create and os.path.isdir(self.path):
- raise util.Abort(_("patch queue directory already exists"))
- try:
- os.mkdir(self.path)
- except OSError, inst:
- if inst.errno != errno.EEXIST or not create:
- raise
- if create:
- return self.qrepo(create=True)
-
- def unapplied(self, repo, patch=None):
- if patch and patch not in self.series:
- raise util.Abort(_("patch %s is not in series file") % patch)
- if not patch:
- start = self.series_end()
- else:
- start = self.series.index(patch) + 1
- unapplied = []
- for i in xrange(start, len(self.series)):
- pushable, reason = self.pushable(i)
- if pushable:
- unapplied.append((i, self.series[i]))
- self.explain_pushable(i)
- return unapplied
-
- def qseries(self, repo, missing=None, start=0, length=None, status=None,
- summary=False):
- def displayname(pfx, patchname, state):
- if pfx:
- self.ui.write(pfx)
- if summary:
- ph = patchheader(self.join(patchname), self.plainmode)
- msg = ph.message and ph.message[0] or ''
- if self.ui.formatted():
- width = self.ui.termwidth() - len(pfx) - len(patchname) - 2
- if width > 0:
- msg = util.ellipsis(msg, width)
- else:
- msg = ''
- self.ui.write(patchname, label='qseries.' + state)
- self.ui.write(': ')
- self.ui.write(msg, label='qseries.message.' + state)
- else:
- self.ui.write(patchname, label='qseries.' + state)
- self.ui.write('\n')
-
- applied = set([p.name for p in self.applied])
- if length is None:
- length = len(self.series) - start
- if not missing:
- if self.ui.verbose:
- idxwidth = len(str(start + length - 1))
- for i in xrange(start, start + length):
- patch = self.series[i]
- if patch in applied:
- char, state = 'A', 'applied'
- elif self.pushable(i)[0]:
- char, state = 'U', 'unapplied'
- else:
- char, state = 'G', 'guarded'
- pfx = ''
- if self.ui.verbose:
- pfx = '%*d %s ' % (idxwidth, i, char)
- elif status and status != char:
- continue
- displayname(pfx, patch, state)
- else:
- msng_list = []
- for root, dirs, files in os.walk(self.path):
- d = root[len(self.path) + 1:]
- for f in files:
- fl = os.path.join(d, f)
- if (fl not in self.series and
- fl not in (self.status_path, self.series_path,
- self.guards_path)
- and not fl.startswith('.')):
- msng_list.append(fl)
- for x in sorted(msng_list):
- pfx = self.ui.verbose and ('D ') or ''
- displayname(pfx, x, 'missing')
-
- def issaveline(self, l):
- if l.name == '.hg.patches.save.line':
- return True
-
- def qrepo(self, create=False):
- ui = self.ui.copy()
- ui.setconfig('paths', 'default', '', overlay=False)
- ui.setconfig('paths', 'default-push', '', overlay=False)
- if create or os.path.isdir(self.join(".hg")):
- return hg.repository(ui, path=self.path, create=create)
-
- def restore(self, repo, rev, delete=None, qupdate=None):
- desc = repo[rev].description().strip()
- lines = desc.splitlines()
- i = 0
- datastart = None
- series = []
- applied = []
- qpp = None
- for i, line in enumerate(lines):
- if line == 'Patch Data:':
- datastart = i + 1
- elif line.startswith('Dirstate:'):
- l = line.rstrip()
- l = l[10:].split(' ')
- qpp = [bin(x) for x in l]
- elif datastart != None:
- l = line.rstrip()
- n, name = l.split(':', 1)
- if n:
- applied.append(statusentry(bin(n), name))
- else:
- series.append(l)
- if datastart is None:
- self.ui.warn(_("No saved patch data found\n"))
- return 1
- self.ui.warn(_("restoring status: %s\n") % lines[0])
- self.full_series = series
- self.applied = applied
- self.parse_series()
- self.series_dirty = 1
- self.applied_dirty = 1
- heads = repo.changelog.heads()
- if delete:
- if rev not in heads:
- self.ui.warn(_("save entry has children, leaving it alone\n"))
- else:
- self.ui.warn(_("removing save entry %s\n") % short(rev))
- pp = repo.dirstate.parents()
- if rev in pp:
- update = True
- else:
- update = False
- self.strip(repo, [rev], update=update, backup='strip')
- if qpp:
- self.ui.warn(_("saved queue repository parents: %s %s\n") %
- (short(qpp[0]), short(qpp[1])))
- if qupdate:
- self.ui.status(_("updating queue directory\n"))
- r = self.qrepo()
- if not r:
- self.ui.warn(_("Unable to load queue repository\n"))
- return 1
- hg.clean(r, qpp[0])
-
- def save(self, repo, msg=None):
- if not self.applied:
- self.ui.warn(_("save: no patches applied, exiting\n"))
- return 1
- if self.issaveline(self.applied[-1]):
- self.ui.warn(_("status is already saved\n"))
- return 1
-
- if not msg:
- msg = _("hg patches saved state")
- else:
- msg = "hg patches: " + msg.rstrip('\r\n')
- r = self.qrepo()
- if r:
- pp = r.dirstate.parents()
- msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
- msg += "\n\nPatch Data:\n"
- msg += ''.join('%s\n' % x for x in self.applied)
- msg += ''.join(':%s\n' % x for x in self.full_series)
- n = repo.commit(msg, force=True)
- if not n:
- self.ui.warn(_("repo commit failed\n"))
- return 1
- self.applied.append(statusentry(n, '.hg.patches.save.line'))
- self.applied_dirty = 1
- self.removeundo(repo)
-
- def full_series_end(self):
- if self.applied:
- p = self.applied[-1].name
- end = self.find_series(p)
- if end is None:
- return len(self.full_series)
- return end + 1
- return 0
-
- def series_end(self, all_patches=False):
- """If all_patches is False, return the index of the next pushable patch
- in the series, or the series length. If all_patches is True, return the
- index of the first patch past the last applied one.
- """
- end = 0
- def next(start):
- if all_patches or start >= len(self.series):
- return start
- for i in xrange(start, len(self.series)):
- p, reason = self.pushable(i)
- if p:
- break
- self.explain_pushable(i)
- return i
- if self.applied:
- p = self.applied[-1].name
- try:
- end = self.series.index(p)
- except ValueError:
- return 0
- return next(end + 1)
- return next(end)
-
- def appliedname(self, index):
- pname = self.applied[index].name
- if not self.ui.verbose:
- p = pname
- else:
- p = str(self.series.index(pname)) + " " + pname
- return p
-
- def qimport(self, repo, files, patchname=None, rev=None, existing=None,
- force=None, git=False):
- def checkseries(patchname):
- if patchname in self.series:
- raise util.Abort(_('patch %s is already in the series file')
- % patchname)
- def checkfile(patchname):
- if not force and os.path.exists(self.join(patchname)):
- raise util.Abort(_('patch "%s" already exists')
- % patchname)
-
- if rev:
- if files:
- raise util.Abort(_('option "-r" not valid when importing '
- 'files'))
- rev = cmdutil.revrange(repo, rev)
- rev.sort(reverse=True)
- if (len(files) > 1 or len(rev) > 1) and patchname:
- raise util.Abort(_('option "-n" not valid when importing multiple '
- 'patches'))
- if rev:
- # If mq patches are applied, we can only import revisions
- # that form a linear path to qbase.
- # Otherwise, they should form a linear path to a head.
- heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
- if len(heads) > 1:
- raise util.Abort(_('revision %d is the root of more than one '
- 'branch') % rev[-1])
- if self.applied:
- base = repo.changelog.node(rev[0])
- if base in [n.node for n in self.applied]:
- raise util.Abort(_('revision %d is already managed')
- % rev[0])
- if heads != [self.applied[-1].node]:
- raise util.Abort(_('revision %d is not the parent of '
- 'the queue') % rev[0])
- base = repo.changelog.rev(self.applied[0].node)
- lastparent = repo.changelog.parentrevs(base)[0]
- else:
- if heads != [repo.changelog.node(rev[0])]:
- raise util.Abort(_('revision %d has unmanaged children')
- % rev[0])
- lastparent = None
-
- diffopts = self.diffopts({'git': git})
- for r in rev:
- p1, p2 = repo.changelog.parentrevs(r)
- n = repo.changelog.node(r)
- if p2 != nullrev:
- raise util.Abort(_('cannot import merge revision %d') % r)
- if lastparent and lastparent != r:
- raise util.Abort(_('revision %d is not the parent of %d')
- % (r, lastparent))
- lastparent = p1
-
- if not patchname:
- patchname = normname('%d.diff' % r)
- self.check_reserved_name(patchname)
- checkseries(patchname)
- checkfile(patchname)
- self.full_series.insert(0, patchname)
-
- patchf = self.opener(patchname, "w")
- cmdutil.export(repo, [n], fp=patchf, opts=diffopts)
- patchf.close()
-
- se = statusentry(n, patchname)
- self.applied.insert(0, se)
-
- self.added.append(patchname)
- patchname = None
- self.parse_series()
- self.applied_dirty = 1
- self.series_dirty = True
-
- for i, filename in enumerate(files):
- if existing:
- if filename == '-':
- raise util.Abort(_('-e is incompatible with import from -'))
- filename = normname(filename)
- self.check_reserved_name(filename)
- originpath = self.join(filename)
- if not os.path.isfile(originpath):
- raise util.Abort(_("patch %s does not exist") % filename)
-
- if patchname:
- self.check_reserved_name(patchname)
- checkfile(patchname)
-
- self.ui.write(_('renaming %s to %s\n')
- % (filename, patchname))
- util.rename(originpath, self.join(patchname))
- else:
- patchname = filename
-
- else:
- try:
- if filename == '-':
- if not patchname:
- raise util.Abort(
- _('need --name to import a patch from -'))
- text = sys.stdin.read()
- else:
- text = url.open(self.ui, filename).read()
- except (OSError, IOError):
- raise util.Abort(_("unable to read file %s") % filename)
- if not patchname:
- patchname = normname(os.path.basename(filename))
- self.check_reserved_name(patchname)
- checkfile(patchname)
- patchf = self.opener(patchname, "w")
- patchf.write(text)
- if not force:
- checkseries(patchname)
- if patchname not in self.series:
- index = self.full_series_end() + i
- self.full_series[index:index] = [patchname]
- self.parse_series()
- self.series_dirty = True
- self.ui.warn(_("adding %s to series file\n") % patchname)
- self.added.append(patchname)
- patchname = None
-
-def delete(ui, repo, *patches, **opts):
- """remove patches from queue
-
- The patches must not be applied, and at least one patch is required. With
- -k/--keep, the patch files are preserved in the patch directory.
-
- To stop managing a patch and move it into permanent history,
- use the :hg:`qfinish` command."""
- q = repo.mq
- q.delete(repo, patches, opts)
- q.save_dirty()
- return 0
-
-def applied(ui, repo, patch=None, **opts):
- """print the patches already applied
-
- Returns 0 on success."""
-
- q = repo.mq
-
- if patch:
- if patch not in q.series:
- raise util.Abort(_("patch %s is not in series file") % patch)
- end = q.series.index(patch) + 1
- else:
- end = q.series_end(True)
-
- if opts.get('last') and not end:
- ui.write(_("no patches applied\n"))
- return 1
- elif opts.get('last') and end == 1:
- ui.write(_("only one patch applied\n"))
- return 1
- elif opts.get('last'):
- start = end - 2
- end = 1
- else:
- start = 0
-
- q.qseries(repo, length=end, start=start, status='A',
- summary=opts.get('summary'))
-
-
-def unapplied(ui, repo, patch=None, **opts):
- """print the patches not yet applied
-
- Returns 0 on success."""
-
- q = repo.mq
- if patch:
- if patch not in q.series:
- raise util.Abort(_("patch %s is not in series file") % patch)
- start = q.series.index(patch) + 1
- else:
- start = q.series_end(True)
-
- if start == len(q.series) and opts.get('first'):
- ui.write(_("all patches applied\n"))
- return 1
-
- length = opts.get('first') and 1 or None
- q.qseries(repo, start=start, length=length, status='U',
- summary=opts.get('summary'))
-
-def qimport(ui, repo, *filename, **opts):
- """import a patch
-
- The patch is inserted into the series after the last applied
- patch. If no patches have been applied, qimport prepends the patch
- to the series.
-
- The patch will have the same name as its source file unless you
- give it a new one with -n/--name.
-
- You can register an existing patch inside the patch directory with
- the -e/--existing flag.
-
- With -f/--force, an existing patch of the same name will be
- overwritten.
-
- An existing changeset may be placed under mq control with -r/--rev
- (e.g. qimport --rev tip -n patch will place tip under mq control).
- With -g/--git, patches imported with --rev will use the git diff
- format. See the diffs help topic for information on why this is
- important for preserving rename/copy information and permission
- changes.
-
- To import a patch from standard input, pass - as the patch file.
- When importing from standard input, a patch name must be specified
- using the --name flag.
-
- To import an existing patch while renaming it::
-
- hg qimport -e existing-patch -n new-name
-
- Returns 0 if import succeeded.
- """
- q = repo.mq
- try:
- q.qimport(repo, filename, patchname=opts.get('name'),
- existing=opts.get('existing'), force=opts.get('force'),
- rev=opts.get('rev'), git=opts.get('git'))
- finally:
- q.save_dirty()
-
- if opts.get('push') and not opts.get('rev'):
- return q.push(repo, None)
- return 0
-
-def qinit(ui, repo, create):
- """initialize a new queue repository
-
- This command also creates a series file for ordering patches, and
- an mq-specific .hgignore file in the queue repository, to exclude
- the status and guards files (these contain mostly transient state).
-
- Returns 0 if initialization succeeded."""
- q = repo.mq
- r = q.init(repo, create)
- q.save_dirty()
- if r:
- if not os.path.exists(r.wjoin('.hgignore')):
- fp = r.wopener('.hgignore', 'w')
- fp.write('^\\.hg\n')
- fp.write('^\\.mq\n')
- fp.write('syntax: glob\n')
- fp.write('status\n')
- fp.write('guards\n')
- fp.close()
- if not os.path.exists(r.wjoin('series')):
- r.wopener('series', 'w').close()
- r[None].add(['.hgignore', 'series'])
- commands.add(ui, r)
- return 0
-
-def init(ui, repo, **opts):
- """init a new queue repository (DEPRECATED)
-
- The queue repository is unversioned by default. If
- -c/--create-repo is specified, qinit will create a separate nested
- repository for patches (qinit -c may also be run later to convert
- an unversioned patch repository into a versioned one). You can use
- qcommit to commit changes to this queue repository.
-
- This command is deprecated. Without -c, it's implied by other relevant
- commands. With -c, use :hg:`init --mq` instead."""
- return qinit(ui, repo, create=opts.get('create_repo'))
-
-def clone(ui, source, dest=None, **opts):
- '''clone main and patch repository at same time
-
- If source is local, destination will have no patches applied. If
- source is remote, this command can not check if patches are
- applied in source, so cannot guarantee that patches are not
- applied in destination. If you clone remote repository, be sure
- before that it has no patches applied.
-
- Source patch repository is looked for in <src>/.hg/patches by
- default. Use -p <url> to change.
-
- The patch directory must be a nested Mercurial repository, as
- would be created by :hg:`init --mq`.
-
- Return 0 on success.
- '''
- def patchdir(repo):
- url = repo.url()
- if url.endswith('/'):
- url = url[:-1]
- return url + '/.hg/patches'
- if dest is None:
- dest = hg.defaultdest(source)
- sr = hg.repository(hg.remoteui(ui, opts), ui.expandpath(source))
- if opts.get('patches'):
- patchespath = ui.expandpath(opts.get('patches'))
- else:
- patchespath = patchdir(sr)
- try:
- hg.repository(ui, patchespath)
- except error.RepoError:
- raise util.Abort(_('versioned patch repository not found'
- ' (see init --mq)'))
- qbase, destrev = None, None
- if sr.local():
- if sr.mq.applied:
- qbase = sr.mq.applied[0].node
- if not hg.islocal(dest):
- heads = set(sr.heads())
- destrev = list(heads.difference(sr.heads(qbase)))
- destrev.append(sr.changelog.parents(qbase)[0])
- elif sr.capable('lookup'):
- try:
- qbase = sr.lookup('qbase')
- except error.RepoError:
- pass
- ui.note(_('cloning main repository\n'))
- sr, dr = hg.clone(ui, sr.url(), dest,
- pull=opts.get('pull'),
- rev=destrev,
- update=False,
- stream=opts.get('uncompressed'))
- ui.note(_('cloning patch repository\n'))
- hg.clone(ui, opts.get('patches') or patchdir(sr), patchdir(dr),
- pull=opts.get('pull'), update=not opts.get('noupdate'),
- stream=opts.get('uncompressed'))
- if dr.local():
- if qbase:
- ui.note(_('stripping applied patches from destination '
- 'repository\n'))
- dr.mq.strip(dr, [qbase], update=False, backup=None)
- if not opts.get('noupdate'):
- ui.note(_('updating destination repository\n'))
- hg.update(dr, dr.changelog.tip())
-
-def commit(ui, repo, *pats, **opts):
- """commit changes in the queue repository (DEPRECATED)
-
- This command is deprecated; use :hg:`commit --mq` instead."""
- q = repo.mq
- r = q.qrepo()
- if not r:
- raise util.Abort('no queue repository')
- commands.commit(r.ui, r, *pats, **opts)
-
-def series(ui, repo, **opts):
- """print the entire series file
-
- Returns 0 on success."""
- repo.mq.qseries(repo, missing=opts.get('missing'), summary=opts.get('summary'))
- return 0
-
-def top(ui, repo, **opts):
- """print the name of the current patch
-
- Returns 0 on success."""
- q = repo.mq
- t = q.applied and q.series_end(True) or 0
- if t:
- q.qseries(repo, start=t - 1, length=1, status='A',
- summary=opts.get('summary'))
- else:
- ui.write(_("no patches applied\n"))
- return 1
-
-def next(ui, repo, **opts):
- """print the name of the next patch
-
- Returns 0 on success."""
- q = repo.mq
- end = q.series_end()
- if end == len(q.series):
- ui.write(_("all patches applied\n"))
- return 1
- q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
-
-def prev(ui, repo, **opts):
- """print the name of the previous patch
-
- Returns 0 on success."""
- q = repo.mq
- l = len(q.applied)
- if l == 1:
- ui.write(_("only one patch applied\n"))
- return 1
- if not l:
- ui.write(_("no patches applied\n"))
- return 1
- q.qseries(repo, start=l - 2, length=1, status='A',
- summary=opts.get('summary'))
-
-def setupheaderopts(ui, opts):
- if not opts.get('user') and opts.get('currentuser'):
- opts['user'] = ui.username()
- if not opts.get('date') and opts.get('currentdate'):
- opts['date'] = "%d %d" % util.makedate()
-
-def new(ui, repo, patch, *args, **opts):
- """create a new patch
-
- qnew creates a new patch on top of the currently-applied patch (if
- any). The patch will be initialized with any outstanding changes
- in the working directory. You may also use -I/--include,
- -X/--exclude, and/or a list of files after the patch name to add
- only changes to matching files to the new patch, leaving the rest
- as uncommitted modifications.
-
- -u/--user and -d/--date can be used to set the (given) user and
- date, respectively. -U/--currentuser and -D/--currentdate set user
- to current user and date to current date.
-
- -e/--edit, -m/--message or -l/--logfile set the patch header as
- well as the commit message. If none is specified, the header is
- empty and the commit message is '[mq]: PATCH'.
-
- Use the -g/--git option to keep the patch in the git extended diff
- format. Read the diffs help topic for more information on why this
- is important for preserving permission changes and copy/rename
- information.
-
- Returns 0 on successful creation of a new patch.
- """
- msg = cmdutil.logmessage(opts)
- def getmsg():
- return ui.edit(msg, opts.get('user') or ui.username())
- q = repo.mq
- opts['msg'] = msg
- if opts.get('edit'):
- opts['msg'] = getmsg
- else:
- opts['msg'] = msg
- setupheaderopts(ui, opts)
- q.new(repo, patch, *args, **opts)
- q.save_dirty()
- return 0
-
-def refresh(ui, repo, *pats, **opts):
- """update the current patch
-
- If any file patterns are provided, the refreshed patch will
- contain only the modifications that match those patterns; the
- remaining modifications will remain in the working directory.
-
- If -s/--short is specified, files currently included in the patch
- will be refreshed just like matched files and remain in the patch.
-
- If -e/--edit is specified, Mercurial will start your configured editor for
- you to enter a message. In case qrefresh fails, you will find a backup of
- your message in ``.hg/last-message.txt``.
-
- hg add/remove/copy/rename work as usual, though you might want to
- use git-style patches (-g/--git or [diff] git=1) to track copies
- and renames. See the diffs help topic for more information on the
- git diff format.
-
- Returns 0 on success.
- """
- q = repo.mq
- message = cmdutil.logmessage(opts)
- if opts.get('edit'):
- if not q.applied:
- ui.write(_("no patches applied\n"))
- return 1
- if message:
- raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
- patch = q.applied[-1].name
- ph = patchheader(q.join(patch), q.plainmode)
- message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
- # We don't want to lose the patch message if qrefresh fails (issue2062)
- msgfile = repo.opener('last-message.txt', 'wb')
- msgfile.write(message)
- msgfile.close()
- setupheaderopts(ui, opts)
- ret = q.refresh(repo, pats, msg=message, **opts)
- q.save_dirty()
- return ret
-
-def diff(ui, repo, *pats, **opts):
- """diff of the current patch and subsequent modifications
-
- Shows a diff which includes the current patch as well as any
- changes which have been made in the working directory since the
- last refresh (thus showing what the current patch would become
- after a qrefresh).
-
- Use :hg:`diff` if you only want to see the changes made since the
- last qrefresh, or :hg:`export qtip` if you want to see changes
- made by the current patch without including changes made since the
- qrefresh.
-
- Returns 0 on success.
- """
- repo.mq.diff(repo, pats, opts)
- return 0
-
-def fold(ui, repo, *files, **opts):
- """fold the named patches into the current patch
-
- Patches must not yet be applied. Each patch will be successively
- applied to the current patch in the order given. If all the
- patches apply successfully, the current patch will be refreshed
- with the new cumulative patch, and the folded patches will be
- deleted. With -k/--keep, the folded patch files will not be
- removed afterwards.
-
- The header for each folded patch will be concatenated with the
- current patch header, separated by a line of ``* * *``.
-
- Returns 0 on success."""
-
- q = repo.mq
-
- if not files:
- raise util.Abort(_('qfold requires at least one patch name'))
- if not q.check_toppatch(repo)[0]:
- raise util.Abort(_('no patches applied'))
- q.check_localchanges(repo)
-
- message = cmdutil.logmessage(opts)
- if opts.get('edit'):
- if message:
- raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
-
- parent = q.lookup('qtip')
- patches = []
- messages = []
- for f in files:
- p = q.lookup(f)
- if p in patches or p == parent:
- ui.warn(_('Skipping already folded patch %s\n') % p)
- if q.isapplied(p):
- raise util.Abort(_('qfold cannot fold already applied patch %s') % p)
- patches.append(p)
-
- for p in patches:
- if not message:
- ph = patchheader(q.join(p), q.plainmode)
- if ph.message:
- messages.append(ph.message)
- pf = q.join(p)
- (patchsuccess, files, fuzz) = q.patch(repo, pf)
- if not patchsuccess:
- raise util.Abort(_('error folding patch %s') % p)
- cmdutil.updatedir(ui, repo, files)
-
- if not message:
- ph = patchheader(q.join(parent), q.plainmode)
- message, user = ph.message, ph.user
- for msg in messages:
- message.append('* * *')
- message.extend(msg)
- message = '\n'.join(message)
-
- if opts.get('edit'):
- message = ui.edit(message, user or ui.username())
-
- diffopts = q.patchopts(q.diffopts(), *patches)
- q.refresh(repo, msg=message, git=diffopts.git)
- q.delete(repo, patches, opts)
- q.save_dirty()
-
-def goto(ui, repo, patch, **opts):
- '''push or pop patches until named patch is at top of stack
-
- Returns 0 on success.'''
- q = repo.mq
- patch = q.lookup(patch)
- if q.isapplied(patch):
- ret = q.pop(repo, patch, force=opts.get('force'))
- else:
- ret = q.push(repo, patch, force=opts.get('force'))
- q.save_dirty()
- return ret
-
-def guard(ui, repo, *args, **opts):
- '''set or print guards for a patch
-
- Guards control whether a patch can be pushed. A patch with no
- guards is always pushed. A patch with a positive guard ("+foo") is
- pushed only if the :hg:`qselect` command has activated it. A patch with
- a negative guard ("-foo") is never pushed if the :hg:`qselect` command
- has activated it.
-
- With no arguments, print the currently active guards.
- With arguments, set guards for the named patch.
-
- .. note::
- Specifying negative guards now requires '--'.
-
- To set guards on another patch::
-
- hg qguard other.patch -- +2.6.17 -stable
-
- Returns 0 on success.
- '''
- def status(idx):
- guards = q.series_guards[idx] or ['unguarded']
- if q.series[idx] in applied:
- state = 'applied'
- elif q.pushable(idx)[0]:
- state = 'unapplied'
- else:
- state = 'guarded'
- label = 'qguard.patch qguard.%s qseries.%s' % (state, state)
- ui.write('%s: ' % ui.label(q.series[idx], label))
-
- for i, guard in enumerate(guards):
- if guard.startswith('+'):
- ui.write(guard, label='qguard.positive')
- elif guard.startswith('-'):
- ui.write(guard, label='qguard.negative')
- else:
- ui.write(guard, label='qguard.unguarded')
- if i != len(guards) - 1:
- ui.write(' ')
- ui.write('\n')
- q = repo.mq
- applied = set(p.name for p in q.applied)
- patch = None
- args = list(args)
- if opts.get('list'):
- if args or opts.get('none'):
- raise util.Abort(_('cannot mix -l/--list with options or arguments'))
- for i in xrange(len(q.series)):
- status(i)
- return
- if not args or args[0][0:1] in '-+':
- if not q.applied:
- raise util.Abort(_('no patches applied'))
- patch = q.applied[-1].name
- if patch is None and args[0][0:1] not in '-+':
- patch = args.pop(0)
- if patch is None:
- raise util.Abort(_('no patch to work with'))
- if args or opts.get('none'):
- idx = q.find_series(patch)
- if idx is None:
- raise util.Abort(_('no patch named %s') % patch)
- q.set_guards(idx, args)
- q.save_dirty()
- else:
- status(q.series.index(q.lookup(patch)))
-
-def header(ui, repo, patch=None):
- """print the header of the topmost or specified patch
-
- Returns 0 on success."""
- q = repo.mq
-
- if patch:
- patch = q.lookup(patch)
- else:
- if not q.applied:
- ui.write(_('no patches applied\n'))
- return 1
- patch = q.lookup('qtip')
- ph = patchheader(q.join(patch), q.plainmode)
-
- ui.write('\n'.join(ph.message) + '\n')
-
-def lastsavename(path):
- (directory, base) = os.path.split(path)
- names = os.listdir(directory)
- namere = re.compile("%s.([0-9]+)" % base)
- maxindex = None
- maxname = None
- for f in names:
- m = namere.match(f)
- if m:
- index = int(m.group(1))
- if maxindex is None or index > maxindex:
- maxindex = index
- maxname = f
- if maxname:
- return (os.path.join(directory, maxname), maxindex)
- return (None, None)
-
-def savename(path):
- (last, index) = lastsavename(path)
- if last is None:
- index = 0
- newpath = path + ".%d" % (index + 1)
- return newpath
-
-def push(ui, repo, patch=None, **opts):
- """push the next patch onto the stack
-
- When -f/--force is applied, all local changes in patched files
- will be lost.
-
- Return 0 on succces.
- """
- q = repo.mq
- mergeq = None
-
- if opts.get('merge'):
- if opts.get('name'):
- newpath = repo.join(opts.get('name'))
- else:
- newpath, i = lastsavename(q.path)
- if not newpath:
- ui.warn(_("no saved queues found, please use -n\n"))
- return 1
- mergeq = queue(ui, repo.join(""), newpath)
- ui.warn(_("merging with queue at: %s\n") % mergeq.path)
- ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
- mergeq=mergeq, all=opts.get('all'), move=opts.get('move'))
- return ret
-
-def pop(ui, repo, patch=None, **opts):
- """pop the current patch off the stack
-
- By default, pops off the top of the patch stack. If given a patch
- name, keeps popping off patches until the named patch is at the
- top of the stack.
-
- Return 0 on success.
- """
- localupdate = True
- if opts.get('name'):
- q = queue(ui, repo.join(""), repo.join(opts.get('name')))
- ui.warn(_('using patch queue: %s\n') % q.path)
- localupdate = False
- else:
- q = repo.mq
- ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
- all=opts.get('all'))
- q.save_dirty()
- return ret
-
-def rename(ui, repo, patch, name=None, **opts):
- """rename a patch
-
- With one argument, renames the current patch to PATCH1.
- With two arguments, renames PATCH1 to PATCH2.
-
- Returns 0 on success."""
-
- q = repo.mq
-
- if not name:
- name = patch
- patch = None
-
- if patch:
- patch = q.lookup(patch)
- else:
- if not q.applied:
- ui.write(_('no patches applied\n'))
- return
- patch = q.lookup('qtip')
- absdest = q.join(name)
- if os.path.isdir(absdest):
- name = normname(os.path.join(name, os.path.basename(patch)))
- absdest = q.join(name)
- if os.path.exists(absdest):
- raise util.Abort(_('%s already exists') % absdest)
-
- if name in q.series:
- raise util.Abort(
- _('A patch named %s already exists in the series file') % name)
-
- ui.note(_('renaming %s to %s\n') % (patch, name))
- i = q.find_series(patch)
- guards = q.guard_re.findall(q.full_series[i])
- q.full_series[i] = name + ''.join([' #' + g for g in guards])
- q.parse_series()
- q.series_dirty = 1
-
- info = q.isapplied(patch)
- if info:
- q.applied[info[0]] = statusentry(info[1], name)
- q.applied_dirty = 1
-
- destdir = os.path.dirname(absdest)
- if not os.path.isdir(destdir):
- os.makedirs(destdir)
- util.rename(q.join(patch), absdest)
- r = q.qrepo()
- if r and patch in r.dirstate:
- wctx = r[None]
- wlock = r.wlock()
- try:
- if r.dirstate[patch] == 'a':
- r.dirstate.forget(patch)
- r.dirstate.add(name)
- else:
- if r.dirstate[name] == 'r':
- wctx.undelete([name])
- wctx.copy(patch, name)
- wctx.remove([patch], False)
- finally:
- wlock.release()
-
- q.save_dirty()
-
-def restore(ui, repo, rev, **opts):
- """restore the queue state saved by a revision (DEPRECATED)
-
- This command is deprecated, use :hg:`rebase` instead."""
- rev = repo.lookup(rev)
- q = repo.mq
- q.restore(repo, rev, delete=opts.get('delete'),
- qupdate=opts.get('update'))
- q.save_dirty()
- return 0
-
-def save(ui, repo, **opts):
- """save current queue state (DEPRECATED)
-
- This command is deprecated, use :hg:`rebase` instead."""
- q = repo.mq
- message = cmdutil.logmessage(opts)
- ret = q.save(repo, msg=message)
- if ret:
- return ret
- q.save_dirty()
- if opts.get('copy'):
- path = q.path
- if opts.get('name'):
- newpath = os.path.join(q.basepath, opts.get('name'))
- if os.path.exists(newpath):
- if not os.path.isdir(newpath):
- raise util.Abort(_('destination %s exists and is not '
- 'a directory') % newpath)
- if not opts.get('force'):
- raise util.Abort(_('destination %s exists, '
- 'use -f to force') % newpath)
- else:
- newpath = savename(path)
- ui.warn(_("copy %s to %s\n") % (path, newpath))
- util.copyfiles(path, newpath)
- if opts.get('empty'):
- try:
- os.unlink(q.join(q.status_path))
- except:
- pass
- return 0
-
-def strip(ui, repo, *revs, **opts):
- """strip changesets and all their descendants from the repository
-
- The strip command removes the specified changesets and all their
- descendants. If the working directory has uncommitted changes,
- the operation is aborted unless the --force flag is supplied.
-
- If a parent of the working directory is stripped, then the working
- directory will automatically be updated to the most recent
- available ancestor of the stripped parent after the operation
- completes.
-
- Any stripped changesets are stored in ``.hg/strip-backup`` as a
- bundle (see :hg:`help bundle` and :hg:`help unbundle`). They can
- be restored by running :hg:`unbundle .hg/strip-backup/BUNDLE`,
- where BUNDLE is the bundle file created by the strip. Note that
- the local revision numbers will in general be different after the
- restore.
-
- Use the --no-backup option to discard the backup bundle once the
- operation completes.
-
- Return 0 on success.
- """
- backup = 'all'
- if opts.get('backup'):
- backup = 'strip'
- elif opts.get('no_backup') or opts.get('nobackup'):
- backup = 'none'
-
- cl = repo.changelog
- revs = set(cmdutil.revrange(repo, revs))
- if not revs:
- raise util.Abort(_('empty revision set'))
-
- descendants = set(cl.descendants(*revs))
- strippedrevs = revs.union(descendants)
- roots = revs.difference(descendants)
-
- update = False
- # if one of the wdir parent is stripped we'll need
- # to update away to an earlier revision
- for p in repo.dirstate.parents():
- if p != nullid and cl.rev(p) in strippedrevs:
- update = True
- break
-
- rootnodes = set(cl.node(r) for r in roots)
-
- q = repo.mq
- if q.applied:
- # refresh queue state if we're about to strip
- # applied patches
- if cl.rev(repo.lookup('qtip')) in strippedrevs:
- q.applied_dirty = True
- start = 0
- end = len(q.applied)
- for i, statusentry in enumerate(q.applied):
- if statusentry.node in rootnodes:
- # if one of the stripped roots is an applied
- # patch, only part of the queue is stripped
- start = i
- break
- del q.applied[start:end]
- q.save_dirty()
-
- revs = list(rootnodes)
- if update and opts.get('keep'):
- wlock = repo.wlock()
- try:
- urev = repo.mq.qparents(repo, revs[0])
- repo.dirstate.rebuild(urev, repo[urev].manifest())
- repo.dirstate.write()
- update = False
- finally:
- wlock.release()
-
- repo.mq.strip(repo, revs, backup=backup, update=update,
- force=opts.get('force'))
- return 0
-
-def select(ui, repo, *args, **opts):
- '''set or print guarded patches to push
-
- Use the :hg:`qguard` command to set or print guards on patch, then use
- qselect to tell mq which guards to use. A patch will be pushed if
- it has no guards or any positive guards match the currently
- selected guard, but will not be pushed if any negative guards
- match the current guard. For example::
-
- qguard foo.patch -stable (negative guard)
- qguard bar.patch +stable (positive guard)
- qselect stable
-
- This activates the "stable" guard. mq will skip foo.patch (because
- it has a negative match) but push bar.patch (because it has a
- positive match).
-
- With no arguments, prints the currently active guards.
- With one argument, sets the active guard.
-
- Use -n/--none to deactivate guards (no other arguments needed).
- When no guards are active, patches with positive guards are
- skipped and patches with negative guards are pushed.
-
- qselect can change the guards on applied patches. It does not pop
- guarded patches by default. Use --pop to pop back to the last
- applied patch that is not guarded. Use --reapply (which implies
- --pop) to push back to the current patch afterwards, but skip
- guarded patches.
-
- Use -s/--series to print a list of all guards in the series file
- (no other arguments needed). Use -v for more information.
-
- Returns 0 on success.'''
-
- q = repo.mq
- guards = q.active()
- if args or opts.get('none'):
- old_unapplied = q.unapplied(repo)
- old_guarded = [i for i in xrange(len(q.applied)) if
- not q.pushable(i)[0]]
- q.set_active(args)
- q.save_dirty()
- if not args:
- ui.status(_('guards deactivated\n'))
- if not opts.get('pop') and not opts.get('reapply'):
- unapplied = q.unapplied(repo)
- guarded = [i for i in xrange(len(q.applied))
- if not q.pushable(i)[0]]
- if len(unapplied) != len(old_unapplied):
- ui.status(_('number of unguarded, unapplied patches has '
- 'changed from %d to %d\n') %
- (len(old_unapplied), len(unapplied)))
- if len(guarded) != len(old_guarded):
- ui.status(_('number of guarded, applied patches has changed '
- 'from %d to %d\n') %
- (len(old_guarded), len(guarded)))
- elif opts.get('series'):
- guards = {}
- noguards = 0
- for gs in q.series_guards:
- if not gs:
- noguards += 1
- for g in gs:
- guards.setdefault(g, 0)
- guards[g] += 1
- if ui.verbose:
- guards['NONE'] = noguards
- guards = guards.items()
- guards.sort(key=lambda x: x[0][1:])
- if guards:
- ui.note(_('guards in series file:\n'))
- for guard, count in guards:
- ui.note('%2d ' % count)
- ui.write(guard, '\n')
- else:
- ui.note(_('no guards in series file\n'))
- else:
- if guards:
- ui.note(_('active guards:\n'))
- for g in guards:
- ui.write(g, '\n')
- else:
- ui.write(_('no active guards\n'))
- reapply = opts.get('reapply') and q.applied and q.appliedname(-1)
- popped = False
- if opts.get('pop') or opts.get('reapply'):
- for i in xrange(len(q.applied)):
- pushable, reason = q.pushable(i)
- if not pushable:
- ui.status(_('popping guarded patches\n'))
- popped = True
- if i == 0:
- q.pop(repo, all=True)
- else:
- q.pop(repo, i - 1)
- break
- if popped:
- try:
- if reapply:
- ui.status(_('reapplying unguarded patches\n'))
- q.push(repo, reapply)
- finally:
- q.save_dirty()
-
-def finish(ui, repo, *revrange, **opts):
- """move applied patches into repository history
-
- Finishes the specified revisions (corresponding to applied
- patches) by moving them out of mq control into regular repository
- history.
-
- Accepts a revision range or the -a/--applied option. If --applied
- is specified, all applied mq revisions are removed from mq
- control. Otherwise, the given revisions must be at the base of the
- stack of applied patches.
-
- This can be especially useful if your changes have been applied to
- an upstream repository, or if you are about to push your changes
- to upstream.
-
- Returns 0 on success.
- """
- if not opts.get('applied') and not revrange:
- raise util.Abort(_('no revisions specified'))
- elif opts.get('applied'):
- revrange = ('qbase::qtip',) + revrange
-
- q = repo.mq
- if not q.applied:
- ui.status(_('no patches applied\n'))
- return 0
-
- revs = cmdutil.revrange(repo, revrange)
- q.finish(repo, revs)
- q.save_dirty()
- return 0
-
-def qqueue(ui, repo, name=None, **opts):
- '''manage multiple patch queues
-
- Supports switching between different patch queues, as well as creating
- new patch queues and deleting existing ones.
-
- Omitting a queue name or specifying -l/--list will show you the registered
- queues - by default the "normal" patches queue is registered. The currently
- active queue will be marked with "(active)".
-
- To create a new queue, use -c/--create. The queue is automatically made
- active, except in the case where there are applied patches from the
- currently active queue in the repository. Then the queue will only be
- created and switching will fail.
-
- To delete an existing queue, use --delete. You cannot delete the currently
- active queue.
-
- Returns 0 on success.
- '''
-
- q = repo.mq
-
- _defaultqueue = 'patches'
- _allqueues = 'patches.queues'
- _activequeue = 'patches.queue'
-
- def _getcurrent():
- cur = os.path.basename(q.path)
- if cur.startswith('patches-'):
- cur = cur[8:]
- return cur
-
- def _noqueues():
- try:
- fh = repo.opener(_allqueues, 'r')
- fh.close()
- except IOError:
- return True
-
- return False
-
- def _getqueues():
- current = _getcurrent()
-
- try:
- fh = repo.opener(_allqueues, 'r')
- queues = [queue.strip() for queue in fh if queue.strip()]
- if current not in queues:
- queues.append(current)
- except IOError:
- queues = [_defaultqueue]
-
- return sorted(queues)
-
- def _setactive(name):
- if q.applied:
- raise util.Abort(_('patches applied - cannot set new queue active'))
- _setactivenocheck(name)
-
- def _setactivenocheck(name):
- fh = repo.opener(_activequeue, 'w')
- if name != 'patches':
- fh.write(name)
- fh.close()
-
- def _addqueue(name):
- fh = repo.opener(_allqueues, 'a')
- fh.write('%s\n' % (name,))
- fh.close()
-
- def _queuedir(name):
- if name == 'patches':
- return repo.join('patches')
- else:
- return repo.join('patches-' + name)
-
- def _validname(name):
- for n in name:
- if n in ':\\/.':
- return False
- return True
-
- def _delete(name):
- if name not in existing:
- raise util.Abort(_('cannot delete queue that does not exist'))
-
- current = _getcurrent()
-
- if name == current:
- raise util.Abort(_('cannot delete currently active queue'))
-
- fh = repo.opener('patches.queues.new', 'w')
- for queue in existing:
- if queue == name:
- continue
- fh.write('%s\n' % (queue,))
- fh.close()
- util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
-
- if not name or opts.get('list'):
- current = _getcurrent()
- for queue in _getqueues():
- ui.write('%s' % (queue,))
- if queue == current and not ui.quiet:
- ui.write(_(' (active)\n'))
- else:
- ui.write('\n')
- return
-
- if not _validname(name):
- raise util.Abort(
- _('invalid queue name, may not contain the characters ":\\/."'))
-
- existing = _getqueues()
-
- if opts.get('create'):
- if name in existing:
- raise util.Abort(_('queue "%s" already exists') % name)
- if _noqueues():
- _addqueue(_defaultqueue)
- _addqueue(name)
- _setactive(name)
- elif opts.get('rename'):
- current = _getcurrent()
- if name == current:
- raise util.Abort(_('can\'t rename "%s" to its current name') % name)
- if name in existing:
- raise util.Abort(_('queue "%s" already exists') % name)
-
- olddir = _queuedir(current)
- newdir = _queuedir(name)
-
- if os.path.exists(newdir):
- raise util.Abort(_('non-queue directory "%s" already exists') %
- newdir)
-
- fh = repo.opener('patches.queues.new', 'w')
- for queue in existing:
- if queue == current:
- fh.write('%s\n' % (name,))
- if os.path.exists(olddir):
- util.rename(olddir, newdir)
- else:
- fh.write('%s\n' % (queue,))
- fh.close()
- util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
- _setactivenocheck(name)
- elif opts.get('delete'):
- _delete(name)
- elif opts.get('purge'):
- if name in existing:
- _delete(name)
- qdir = _queuedir(name)
- if os.path.exists(qdir):
- shutil.rmtree(qdir)
- else:
- if name not in existing:
- raise util.Abort(_('use --create to create a new queue'))
- _setactive(name)
-
-def reposetup(ui, repo):
- class mqrepo(repo.__class__):
- @util.propertycache
- def mq(self):
- return queue(self.ui, self.join(""))
-
- def abort_if_wdir_patched(self, errmsg, force=False):
- if self.mq.applied and not force:
- parent = self.dirstate.parents()[0]
- if parent in [s.node for s in self.mq.applied]:
- raise util.Abort(errmsg)
-
- def commit(self, text="", user=None, date=None, match=None,
- force=False, editor=False, extra={}):
- self.abort_if_wdir_patched(
- _('cannot commit over an applied mq patch'),
- force)
-
- return super(mqrepo, self).commit(text, user, date, match, force,
- editor, extra)
-
- def push(self, remote, force=False, revs=None, newbranch=False):
- if self.mq.applied and not force:
- haspatches = True
- if revs:
- # Assume applied patches have no non-patch descendants
- # and are not on remote already. If they appear in the
- # set of resolved 'revs', bail out.
- applied = set(e.node for e in self.mq.applied)
- haspatches = bool([n for n in revs if n in applied])
- if haspatches:
- raise util.Abort(_('source has mq patches applied'))
- return super(mqrepo, self).push(remote, force, revs, newbranch)
-
- def _findtags(self):
- '''augment tags from base class with patch tags'''
- result = super(mqrepo, self)._findtags()
-
- q = self.mq
- if not q.applied:
- return result
-
- mqtags = [(patch.node, patch.name) for patch in q.applied]
-
- if mqtags[-1][0] not in self.changelog.nodemap:
- self.ui.warn(_('mq status file refers to unknown node %s\n')
- % short(mqtags[-1][0]))
- return result
-
- mqtags.append((mqtags[-1][0], 'qtip'))
- mqtags.append((mqtags[0][0], 'qbase'))
- mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
- tags = result[0]
- for patch in mqtags:
- if patch[1] in tags:
- self.ui.warn(_('Tag %s overrides mq patch of the same name\n')
- % patch[1])
- else:
- tags[patch[1]] = patch[0]
-
- return result
-
- def _branchtags(self, partial, lrev):
- q = self.mq
- if not q.applied:
- return super(mqrepo, self)._branchtags(partial, lrev)
-
- cl = self.changelog
- qbasenode = q.applied[0].node
- if qbasenode not in cl.nodemap:
- self.ui.warn(_('mq status file refers to unknown node %s\n')
- % short(qbasenode))
- return super(mqrepo, self)._branchtags(partial, lrev)
-
- qbase = cl.rev(qbasenode)
- start = lrev + 1
- if start < qbase:
- # update the cache (excluding the patches) and save it
- ctxgen = (self[r] for r in xrange(lrev + 1, qbase))
- self._updatebranchcache(partial, ctxgen)
- self._writebranchcache(partial, cl.node(qbase - 1), qbase - 1)
- start = qbase
- # if start = qbase, the cache is as updated as it should be.
- # if start > qbase, the cache includes (part of) the patches.
- # we might as well use it, but we won't save it.
-
- # update the cache up to the tip
- ctxgen = (self[r] for r in xrange(start, len(cl)))
- self._updatebranchcache(partial, ctxgen)
-
- return partial
-
- if repo.local():
- repo.__class__ = mqrepo
-
-def mqimport(orig, ui, repo, *args, **kwargs):
- if (hasattr(repo, 'abort_if_wdir_patched')
- and not kwargs.get('no_commit', False)):
- repo.abort_if_wdir_patched(_('cannot import over an applied patch'),
- kwargs.get('force'))
- return orig(ui, repo, *args, **kwargs)
-
-def mqinit(orig, ui, *args, **kwargs):
- mq = kwargs.pop('mq', None)
-
- if not mq:
- return orig(ui, *args, **kwargs)
-
- if args:
- repopath = args[0]
- if not hg.islocal(repopath):
- raise util.Abort(_('only a local queue repository '
- 'may be initialized'))
- else:
- repopath = cmdutil.findrepo(os.getcwd())
- if not repopath:
- raise util.Abort(_('there is no Mercurial repository here '
- '(.hg not found)'))
- repo = hg.repository(ui, repopath)
- return qinit(ui, repo, True)
-
-def mqcommand(orig, ui, repo, *args, **kwargs):
- """Add --mq option to operate on patch repository instead of main"""
-
- # some commands do not like getting unknown options
- mq = kwargs.pop('mq', None)
-
- if not mq:
- return orig(ui, repo, *args, **kwargs)
-
- q = repo.mq
- r = q.qrepo()
- if not r:
- raise util.Abort(_('no queue repository'))
- return orig(r.ui, r, *args, **kwargs)
-
-def summary(orig, ui, repo, *args, **kwargs):
- r = orig(ui, repo, *args, **kwargs)
- q = repo.mq
- m = []
- a, u = len(q.applied), len(q.unapplied(repo))
- if a:
- m.append(ui.label(_("%d applied"), 'qseries.applied') % a)
- if u:
- m.append(ui.label(_("%d unapplied"), 'qseries.unapplied') % u)
- if m:
- ui.write("mq: %s\n" % ', '.join(m))
- else:
- ui.note(_("mq: (empty queue)\n"))
- return r
-
-def uisetup(ui):
- mqopt = [('', 'mq', None, _("operate on patch repository"))]
-
- extensions.wrapcommand(commands.table, 'import', mqimport)
- extensions.wrapcommand(commands.table, 'summary', summary)
-
- entry = extensions.wrapcommand(commands.table, 'init', mqinit)
- entry[1].extend(mqopt)
-
- nowrap = set(commands.norepo.split(" ") + ['qrecord'])
-
- def dotable(cmdtable):
- for cmd in cmdtable.keys():
- cmd = cmdutil.parsealiases(cmd)[0]
- if cmd in nowrap:
- continue
- entry = extensions.wrapcommand(cmdtable, cmd, mqcommand)
- entry[1].extend(mqopt)
-
- dotable(commands.table)
-
- for extname, extmodule in extensions.extensions():
- if extmodule.__file__ != __file__:
- dotable(getattr(extmodule, 'cmdtable', {}))
-
-seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
-
-cmdtable = {
- "qapplied":
- (applied,
- [('1', 'last', None, _('show only the last patch'))] + seriesopts,
- _('hg qapplied [-1] [-s] [PATCH]')),
- "qclone":
- (clone,
- [('', 'pull', None, _('use pull protocol to copy metadata')),
- ('U', 'noupdate', None, _('do not update the new working directories')),
- ('', 'uncompressed', None,
- _('use uncompressed transfer (fast over LAN)')),
- ('p', 'patches', '',
- _('location of source patch repository'), _('REPO')),
- ] + commands.remoteopts,
- _('hg qclone [OPTION]... SOURCE [DEST]')),
- "qcommit|qci":
- (commit,
- commands.table["^commit|ci"][1],
- _('hg qcommit [OPTION]... [FILE]...')),
- "^qdiff":
- (diff,
- commands.diffopts + commands.diffopts2 + commands.walkopts,
- _('hg qdiff [OPTION]... [FILE]...')),
- "qdelete|qremove|qrm":
- (delete,
- [('k', 'keep', None, _('keep patch file')),
- ('r', 'rev', [],
- _('stop managing a revision (DEPRECATED)'), _('REV'))],
- _('hg qdelete [-k] [PATCH]...')),
- 'qfold':
- (fold,
- [('e', 'edit', None, _('edit patch header')),
- ('k', 'keep', None, _('keep folded patch files')),
- ] + commands.commitopts,
- _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...')),
- 'qgoto':
- (goto,
- [('f', 'force', None, _('overwrite any local changes'))],
- _('hg qgoto [OPTION]... PATCH')),
- 'qguard':
- (guard,
- [('l', 'list', None, _('list all patches and guards')),
- ('n', 'none', None, _('drop all guards'))],
- _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]')),
- 'qheader': (header, [], _('hg qheader [PATCH]')),
- "qimport":
- (qimport,
- [('e', 'existing', None, _('import file in patch directory')),
- ('n', 'name', '',
- _('name of patch file'), _('NAME')),
- ('f', 'force', None, _('overwrite existing files')),
- ('r', 'rev', [],
- _('place existing revisions under mq control'), _('REV')),
- ('g', 'git', None, _('use git extended diff format')),
- ('P', 'push', None, _('qpush after importing'))],
- _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...')),
- "^qinit":
- (init,
- [('c', 'create-repo', None, _('create queue repository'))],
- _('hg qinit [-c]')),
- "^qnew":
- (new,
- [('e', 'edit', None, _('edit commit message')),
- ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
- ('g', 'git', None, _('use git extended diff format')),
- ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
- ('u', 'user', '',
- _('add "From: <USER>" to patch'), _('USER')),
- ('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
- ('d', 'date', '',
- _('add "Date: <DATE>" to patch'), _('DATE'))
- ] + commands.walkopts + commands.commitopts,
- _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...')),
- "qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
- "qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
- "^qpop":
- (pop,
- [('a', 'all', None, _('pop all patches')),
- ('n', 'name', '',
- _('queue name to pop (DEPRECATED)'), _('NAME')),
- ('f', 'force', None, _('forget any local changes to patched files'))],
- _('hg qpop [-a] [-f] [PATCH | INDEX]')),
- "^qpush":
- (push,
- [('f', 'force', None, _('apply on top of local changes')),
- ('l', 'list', None, _('list patch name in commit text')),
- ('a', 'all', None, _('apply all patches')),
- ('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
- ('n', 'name', '',
- _('merge queue name (DEPRECATED)'), _('NAME')),
- ('', 'move', None, _('reorder patch series and apply only the patch'))],
- _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]')),
- "^qrefresh":
- (refresh,
- [('e', 'edit', None, _('edit commit message')),
- ('g', 'git', None, _('use git extended diff format')),
- ('s', 'short', None,
- _('refresh only files already in the patch and specified files')),
- ('U', 'currentuser', None,
- _('add/update author field in patch with current user')),
- ('u', 'user', '',
- _('add/update author field in patch with given user'), _('USER')),
- ('D', 'currentdate', None,
- _('add/update date field in patch with current date')),
- ('d', 'date', '',
- _('add/update date field in patch with given date'), _('DATE'))
- ] + commands.walkopts + commands.commitopts,
- _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
- 'qrename|qmv':
- (rename, [], _('hg qrename PATCH1 [PATCH2]')),
- "qrestore":
- (restore,
- [('d', 'delete', None, _('delete save entry')),
- ('u', 'update', None, _('update queue working directory'))],
- _('hg qrestore [-d] [-u] REV')),
- "qsave":
- (save,
- [('c', 'copy', None, _('copy patch directory')),
- ('n', 'name', '',
- _('copy directory name'), _('NAME')),
- ('e', 'empty', None, _('clear queue status file')),
- ('f', 'force', None, _('force copy'))] + commands.commitopts,
- _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]')),
- "qselect":
- (select,
- [('n', 'none', None, _('disable all guards')),
- ('s', 'series', None, _('list all guards in series file')),
- ('', 'pop', None, _('pop to before first guarded applied patch')),
- ('', 'reapply', None, _('pop, then reapply patches'))],
- _('hg qselect [OPTION]... [GUARD]...')),
- "qseries":
- (series,
- [('m', 'missing', None, _('print patches not in series')),
- ] + seriesopts,
- _('hg qseries [-ms]')),
- "strip":
- (strip,
- [('f', 'force', None, _('force removal of changesets even if the '
- 'working directory has uncommitted changes')),
- ('b', 'backup', None, _('bundle only changesets with local revision'
- ' number greater than REV which are not'
- ' descendants of REV (DEPRECATED)')),
- ('n', 'no-backup', None, _('no backups')),
- ('', 'nobackup', None, _('no backups (DEPRECATED)')),
- ('k', 'keep', None, _("do not modify working copy during strip"))],
- _('hg strip [-k] [-f] [-n] REV...')),
- "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
- "qunapplied":
- (unapplied,
- [('1', 'first', None, _('show only the first patch'))] + seriesopts,
- _('hg qunapplied [-1] [-s] [PATCH]')),
- "qfinish":
- (finish,
- [('a', 'applied', None, _('finish all applied changesets'))],
- _('hg qfinish [-a] [REV]...')),
- 'qqueue':
- (qqueue,
- [
- ('l', 'list', False, _('list all available queues')),
- ('c', 'create', False, _('create new queue')),
- ('', 'rename', False, _('rename active queue')),
- ('', 'delete', False, _('delete reference to queue')),
- ('', 'purge', False, _('delete queue, and remove patch dir')),
- ],
- _('[OPTION] [QUEUE]')),
-}
-
-colortable = {'qguard.negative': 'red',
- 'qguard.positive': 'yellow',
- 'qguard.unguarded': 'green',
- 'qseries.applied': 'blue bold underline',
- 'qseries.guarded': 'black bold',
- 'qseries.missing': 'red bold',
- 'qseries.unapplied': 'black bold'}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.pyo
deleted file mode 100644
index ed0654f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/mq.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.py
deleted file mode 100644
index 5ce2eee..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# notify.py - email notifications for mercurial
-#
-# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''hooks for sending email notifications at commit/push time
-
-Subscriptions can be managed through a hgrc file. Default mode is to
-print messages to stdout, for testing and configuring.
-
-To use, configure the notify extension and enable it in hgrc like
-this::
-
- [extensions]
- notify =
-
- [hooks]
- # one email for each incoming changeset
- incoming.notify = python:hgext.notify.hook
- # batch emails when many changesets incoming at one time
- changegroup.notify = python:hgext.notify.hook
-
- [notify]
- # config items go here
-
-Required configuration items::
-
- config = /path/to/file # file containing subscriptions
-
-Optional configuration items::
-
- test = True # print messages to stdout for testing
- strip = 3 # number of slashes to strip for url paths
- domain = example.com # domain to use if committer missing domain
- style = ... # style file to use when formatting email
- template = ... # template to use when formatting email
- incoming = ... # template to use when run as incoming hook
- changegroup = ... # template when run as changegroup hook
- maxdiff = 300 # max lines of diffs to include (0=none, -1=all)
- maxsubject = 67 # truncate subject line longer than this
- diffstat = True # add a diffstat before the diff content
- sources = serve # notify if source of incoming changes in this list
- # (serve == ssh or http, push, pull, bundle)
- merge = False # send notification for merges (default True)
- [email]
- from = user@host.com # email address to send as if none given
- [web]
- baseurl = http://hgserver/... # root of hg web site for browsing commits
-
-The notify config file has same format as a regular hgrc file. It has
-two sections so you can express subscriptions in whatever way is
-handier for you.
-
-::
-
- [usersubs]
- # key is subscriber email, value is ","-separated list of glob patterns
- user@host = pattern
-
- [reposubs]
- # key is glob pattern, value is ","-separated list of subscriber emails
- pattern = user@host
-
-Glob patterns are matched against path to repository root.
-
-If you like, you can put notify config file in repository that users
-can push changes to, they can manage their own subscriptions.
-'''
-
-from mercurial.i18n import _
-from mercurial import patch, cmdutil, templater, util, mail
-import email.Parser, email.Errors, fnmatch, socket, time
-
-# template for single changeset can include email headers.
-single_template = '''
-Subject: changeset in {webroot}: {desc|firstline|strip}
-From: {author}
-
-changeset {node|short} in {root}
-details: {baseurl}{webroot}?cmd=changeset;node={node|short}
-description:
-\t{desc|tabindent|strip}
-'''.lstrip()
-
-# template for multiple changesets should not contain email headers,
-# because only first set of headers will be used and result will look
-# strange.
-multiple_template = '''
-changeset {node|short} in {root}
-details: {baseurl}{webroot}?cmd=changeset;node={node|short}
-summary: {desc|firstline}
-'''
-
-deftemplates = {
- 'changegroup': multiple_template,
-}
-
-class notifier(object):
- '''email notification class.'''
-
- def __init__(self, ui, repo, hooktype):
- self.ui = ui
- cfg = self.ui.config('notify', 'config')
- if cfg:
- self.ui.readconfig(cfg, sections=['usersubs', 'reposubs'])
- self.repo = repo
- self.stripcount = int(self.ui.config('notify', 'strip', 0))
- self.root = self.strip(self.repo.root)
- self.domain = self.ui.config('notify', 'domain')
- self.test = self.ui.configbool('notify', 'test', True)
- self.charsets = mail._charsets(self.ui)
- self.subs = self.subscribers()
- self.merge = self.ui.configbool('notify', 'merge', True)
-
- mapfile = self.ui.config('notify', 'style')
- template = (self.ui.config('notify', hooktype) or
- self.ui.config('notify', 'template'))
- self.t = cmdutil.changeset_templater(self.ui, self.repo,
- False, None, mapfile, False)
- if not mapfile and not template:
- template = deftemplates.get(hooktype) or single_template
- if template:
- template = templater.parsestring(template, quoted=False)
- self.t.use_template(template)
-
- def strip(self, path):
- '''strip leading slashes from local path, turn into web-safe path.'''
-
- path = util.pconvert(path)
- count = self.stripcount
- while count > 0:
- c = path.find('/')
- if c == -1:
- break
- path = path[c + 1:]
- count -= 1
- return path
-
- def fixmail(self, addr):
- '''try to clean up email addresses.'''
-
- addr = util.email(addr.strip())
- if self.domain:
- a = addr.find('@localhost')
- if a != -1:
- addr = addr[:a]
- if '@' not in addr:
- return addr + '@' + self.domain
- return addr
-
- def subscribers(self):
- '''return list of email addresses of subscribers to this repo.'''
- subs = set()
- for user, pats in self.ui.configitems('usersubs'):
- for pat in pats.split(','):
- if fnmatch.fnmatch(self.repo.root, pat.strip()):
- subs.add(self.fixmail(user))
- for pat, users in self.ui.configitems('reposubs'):
- if fnmatch.fnmatch(self.repo.root, pat):
- for user in users.split(','):
- subs.add(self.fixmail(user))
- return [mail.addressencode(self.ui, s, self.charsets, self.test)
- for s in sorted(subs)]
-
- def url(self, path=None):
- return self.ui.config('web', 'baseurl') + (path or self.root)
-
- def node(self, ctx, **props):
- '''format one changeset, unless it is a suppressed merge.'''
- if not self.merge and len(ctx.parents()) > 1:
- return False
- self.t.show(ctx, changes=ctx.changeset(),
- baseurl=self.ui.config('web', 'baseurl'),
- root=self.repo.root, webroot=self.root, **props)
- return True
-
- def skipsource(self, source):
- '''true if incoming changes from this source should be skipped.'''
- ok_sources = self.ui.config('notify', 'sources', 'serve').split()
- return source not in ok_sources
-
- def send(self, ctx, count, data):
- '''send message.'''
-
- p = email.Parser.Parser()
- try:
- msg = p.parsestr(data)
- except email.Errors.MessageParseError, inst:
- raise util.Abort(inst)
-
- # store sender and subject
- sender, subject = msg['From'], msg['Subject']
- del msg['From'], msg['Subject']
-
- if not msg.is_multipart():
- # create fresh mime message from scratch
- # (multipart templates must take care of this themselves)
- headers = msg.items()
- payload = msg.get_payload()
- # for notification prefer readability over data precision
- msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
- # reinstate custom headers
- for k, v in headers:
- msg[k] = v
-
- msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
-
- # try to make subject line exist and be useful
- if not subject:
- if count > 1:
- subject = _('%s: %d new changesets') % (self.root, count)
- else:
- s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
- subject = '%s: %s' % (self.root, s)
- maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
- if maxsubject:
- subject = util.ellipsis(subject, maxsubject)
- msg['Subject'] = mail.headencode(self.ui, subject,
- self.charsets, self.test)
-
- # try to make message have proper sender
- if not sender:
- sender = self.ui.config('email', 'from') or self.ui.username()
- if '@' not in sender or '@localhost' in sender:
- sender = self.fixmail(sender)
- msg['From'] = mail.addressencode(self.ui, sender,
- self.charsets, self.test)
-
- msg['X-Hg-Notification'] = 'changeset %s' % ctx
- if not msg['Message-Id']:
- msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' %
- (ctx, int(time.time()),
- hash(self.repo.root), socket.getfqdn()))
- msg['To'] = ', '.join(self.subs)
-
- msgtext = msg.as_string()
- if self.test:
- self.ui.write(msgtext)
- if not msgtext.endswith('\n'):
- self.ui.write('\n')
- else:
- self.ui.status(_('notify: sending %d subscribers %d changes\n') %
- (len(self.subs), count))
- mail.sendmail(self.ui, util.email(msg['From']),
- self.subs, msgtext)
-
- def diff(self, ctx, ref=None):
-
- maxdiff = int(self.ui.config('notify', 'maxdiff', 300))
- prev = ctx.parents()[0].node()
- ref = ref and ref.node() or ctx.node()
- chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui))
- difflines = ''.join(chunks).splitlines()
-
- if self.ui.configbool('notify', 'diffstat', True):
- s = patch.diffstat(difflines)
- # s may be nil, don't include the header if it is
- if s:
- self.ui.write('\ndiffstat:\n\n%s' % s)
-
- if maxdiff == 0:
- return
- elif maxdiff > 0 and len(difflines) > maxdiff:
- msg = _('\ndiffs (truncated from %d to %d lines):\n\n')
- self.ui.write(msg % (len(difflines), maxdiff))
- difflines = difflines[:maxdiff]
- elif difflines:
- self.ui.write(_('\ndiffs (%d lines):\n\n') % len(difflines))
-
- self.ui.write("\n".join(difflines))
-
-def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
- '''send email notifications to interested subscribers.
-
- if used as changegroup hook, send one email for all changesets in
- changegroup. else send one email per changeset.'''
-
- n = notifier(ui, repo, hooktype)
- ctx = repo[node]
-
- if not n.subs:
- ui.debug('notify: no subscribers to repository %s\n' % n.root)
- return
- if n.skipsource(source):
- ui.debug('notify: changes have source "%s" - skipping\n' % source)
- return
-
- ui.pushbuffer()
- data = ''
- count = 0
- if hooktype == 'changegroup':
- start, end = ctx.rev(), len(repo)
- for rev in xrange(start, end):
- if n.node(repo[rev]):
- count += 1
- else:
- data += ui.popbuffer()
- ui.note(_('notify: suppressing notification for merge %d:%s\n') %
- (rev, repo[rev].hex()[:12]))
- ui.pushbuffer()
- if count:
- n.diff(ctx, repo['tip'])
- else:
- if not n.node(ctx):
- ui.popbuffer()
- ui.note(_('notify: suppressing notification for merge %d:%s\n') %
- (ctx.rev(), ctx.hex()[:12]))
- return
- count += 1
- n.diff(ctx)
-
- data += ui.popbuffer()
- if count:
- n.send(ctx, count, data)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.pyo
deleted file mode 100644
index 087cf73..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/notify.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.py
deleted file mode 100644
index 6d73c34..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# pager.py - display output using a pager
-#
-# Copyright 2008 David Soria Parra <dsp@php.net>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-#
-# To load the extension, add it to your configuration file:
-#
-# [extension]
-# pager =
-#
-# Run "hg help pager" to get info on configuration.
-
-'''browse command output with an external pager
-
-To set the pager that should be used, set the application variable::
-
- [pager]
- pager = less -FRSX
-
-If no pager is set, the pager extensions uses the environment variable
-$PAGER. If neither pager.pager, nor $PAGER is set, no pager is used.
-
-If you notice "BROKEN PIPE" error messages, you can disable them by
-setting::
-
- [pager]
- quiet = True
-
-You can disable the pager for certain commands by adding them to the
-pager.ignore list::
-
- [pager]
- ignore = version, help, update
-
-You can also enable the pager only for certain commands using
-pager.attend. Below is the default list of commands to be paged::
-
- [pager]
- attend = annotate, cat, diff, export, glog, log, qdiff
-
-Setting pager.attend to an empty value will cause all commands to be
-paged.
-
-If pager.attend is present, pager.ignore will be ignored.
-
-To ignore global commands like :hg:`version` or :hg:`help`, you have
-to specify them in your user configuration file.
-
-The --pager=... option can also be used to control when the pager is
-used. Use a boolean value like yes, no, on, off, or use auto for
-normal behavior.
-'''
-
-import sys, os, signal, shlex, errno
-from mercurial import commands, dispatch, util, extensions
-from mercurial.i18n import _
-
-def _runpager(p):
- if not hasattr(os, 'fork'):
- sys.stderr = sys.stdout = util.popen(p, 'wb')
- return
- fdin, fdout = os.pipe()
- pid = os.fork()
- if pid == 0:
- os.close(fdin)
- os.dup2(fdout, sys.stdout.fileno())
- os.dup2(fdout, sys.stderr.fileno())
- os.close(fdout)
- return
- os.dup2(fdin, sys.stdin.fileno())
- os.close(fdin)
- os.close(fdout)
- try:
- os.execvp('/bin/sh', ['/bin/sh', '-c', p])
- except OSError, e:
- if e.errno == errno.ENOENT:
- # no /bin/sh, try executing the pager directly
- args = shlex.split(p)
- os.execvp(args[0], args)
- else:
- raise
-
-def uisetup(ui):
- if ui.plain():
- return
-
- def pagecmd(orig, ui, options, cmd, cmdfunc):
- p = ui.config("pager", "pager", os.environ.get("PAGER"))
- if p and sys.stdout.isatty() and '--debugger' not in sys.argv:
- attend = ui.configlist('pager', 'attend', attended)
- auto = options['pager'] == 'auto'
- always = util.parsebool(options['pager'])
- if (always or auto and
- (cmd in attend or
- (cmd not in ui.configlist('pager', 'ignore') and not attend))):
- ui.setconfig('ui', 'formatted', ui.formatted())
- ui.setconfig('ui', 'interactive', False)
- _runpager(p)
- if ui.configbool('pager', 'quiet'):
- signal.signal(signal.SIGPIPE, signal.SIG_DFL)
- return orig(ui, options, cmd, cmdfunc)
-
- extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
-
-def extsetup(ui):
- commands.globalopts.append(
- ('', 'pager', 'auto',
- _("when to paginate (boolean, always, auto, or never)"),
- _('TYPE')))
-
-attended = ['annotate', 'cat', 'diff', 'export', 'glog', 'log', 'qdiff']
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.pyo
deleted file mode 100644
index 0b020cf..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/pager.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.py
deleted file mode 100644
index d66be24..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Mercurial extension to make it easy to refer to the parent of a revision
-#
-# Copyright (C) 2007 Alexis S. L. Carvalho <alexis@cecm.usp.br>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''interpret suffixes to refer to ancestor revisions
-
-This extension allows you to use git-style suffixes to refer to the
-ancestors of a specific revision.
-
-For example, if you can refer to a revision as "foo", then::
-
- foo^N = Nth parent of foo
- foo^0 = foo
- foo^1 = first parent of foo
- foo^2 = second parent of foo
- foo^ = foo^1
-
- foo~N = Nth first grandparent of foo
- foo~0 = foo
- foo~1 = foo^1 = foo^ = first parent of foo
- foo~2 = foo^1^1 = foo^^ = first parent of first parent of foo
-'''
-from mercurial import error
-
-def reposetup(ui, repo):
- if not repo.local():
- return
-
- class parentrevspecrepo(repo.__class__):
- def lookup(self, key):
- try:
- _super = super(parentrevspecrepo, self)
- return _super.lookup(key)
- except error.RepoError:
- pass
-
- circ = key.find('^')
- tilde = key.find('~')
- if circ < 0 and tilde < 0:
- raise
- elif circ >= 0 and tilde >= 0:
- end = min(circ, tilde)
- else:
- end = max(circ, tilde)
-
- cl = self.changelog
- base = key[:end]
- try:
- node = _super.lookup(base)
- except error.RepoError:
- # eek - reraise the first error
- return _super.lookup(key)
-
- rev = cl.rev(node)
- suffix = key[end:]
- i = 0
- while i < len(suffix):
- # foo^N => Nth parent of foo
- # foo^0 == foo
- # foo^1 == foo^ == 1st parent of foo
- # foo^2 == 2nd parent of foo
- if suffix[i] == '^':
- j = i + 1
- p = cl.parentrevs(rev)
- if j < len(suffix) and suffix[j].isdigit():
- j += 1
- n = int(suffix[i + 1:j])
- if n > 2 or n == 2 and p[1] == -1:
- raise
- else:
- n = 1
- if n:
- rev = p[n - 1]
- i = j
- # foo~N => Nth first grandparent of foo
- # foo~0 = foo
- # foo~1 = foo^1 == foo^ == 1st parent of foo
- # foo~2 = foo^1^1 == foo^^ == 1st parent of 1st parent of foo
- elif suffix[i] == '~':
- j = i + 1
- while j < len(suffix) and suffix[j].isdigit():
- j += 1
- if j == i + 1:
- raise
- n = int(suffix[i + 1:j])
- for k in xrange(n):
- rev = cl.parentrevs(rev)[0]
- i = j
- else:
- raise
- return cl.node(rev)
-
- repo.__class__ = parentrevspecrepo
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.pyo
deleted file mode 100644
index 3a5be89..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/parentrevspec.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.py
deleted file mode 100644
index 93ea4cb..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.py
+++ /dev/null
@@ -1,553 +0,0 @@
-# patchbomb.py - sending Mercurial changesets as patch emails
-#
-# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to send changesets as (a series of) patch emails
-
-The series is started off with a "[PATCH 0 of N]" introduction, which
-describes the series as a whole.
-
-Each patch email has a Subject line of "[PATCH M of N] ...", using the
-first line of the changeset description as the subject text. The
-message contains two or three body parts:
-
-- The changeset description.
-- [Optional] The result of running diffstat on the patch.
-- The patch itself, as generated by :hg:`export`.
-
-Each message refers to the first in the series using the In-Reply-To
-and References headers, so they will show up as a sequence in threaded
-mail and news readers, and in mail archives.
-
-To configure other defaults, add a section like this to your hgrc
-file::
-
- [email]
- from = My Name <my@email>
- to = recipient1, recipient2, ...
- cc = cc1, cc2, ...
- bcc = bcc1, bcc2, ...
- reply-to = address1, address2, ...
-
-Use ``[patchbomb]`` as configuration section name if you need to
-override global ``[email]`` address settings.
-
-Then you can use the :hg:`email` command to mail a series of
-changesets as a patchbomb.
-
-You can also either configure the method option in the email section
-to be a sendmail compatible mailer or fill out the [smtp] section so
-that the patchbomb extension can automatically send patchbombs
-directly from the commandline. See the [email] and [smtp] sections in
-hgrc(5) for details.
-'''
-
-import os, errno, socket, tempfile, cStringIO, time
-import email.MIMEMultipart, email.MIMEBase
-import email.Utils, email.Encoders, email.Generator
-from mercurial import cmdutil, commands, hg, mail, patch, util, discovery, url
-from mercurial.i18n import _
-from mercurial.node import bin
-
-def prompt(ui, prompt, default=None, rest=':'):
- if not ui.interactive() and default is None:
- raise util.Abort(_("%s Please enter a valid value" % (prompt + rest)))
- if default:
- prompt += ' [%s]' % default
- prompt += rest
- while True:
- r = ui.prompt(prompt, default=default)
- if r:
- return r
- if default is not None:
- return default
- ui.warn(_('Please enter a valid value.\n'))
-
-def introneeded(opts, number):
- '''is an introductory message required?'''
- return number > 1 or opts.get('intro') or opts.get('desc')
-
-def makepatch(ui, repo, patchlines, opts, _charsets, idx, total,
- patchname=None):
-
- desc = []
- node = None
- body = ''
-
- for line in patchlines:
- if line.startswith('#'):
- if line.startswith('# Node ID'):
- node = line.split()[-1]
- continue
- if line.startswith('diff -r') or line.startswith('diff --git'):
- break
- desc.append(line)
-
- if not patchname and not node:
- raise ValueError
-
- if opts.get('attach'):
- body = ('\n'.join(desc[1:]).strip() or
- 'Patch subject is complete summary.')
- body += '\n\n\n'
-
- if opts.get('plain'):
- while patchlines and patchlines[0].startswith('# '):
- patchlines.pop(0)
- if patchlines:
- patchlines.pop(0)
- while patchlines and not patchlines[0].strip():
- patchlines.pop(0)
-
- ds = patch.diffstat(patchlines)
- if opts.get('diffstat'):
- body += ds + '\n\n'
-
- if opts.get('attach') or opts.get('inline'):
- msg = email.MIMEMultipart.MIMEMultipart()
- if body:
- msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
- p = mail.mimetextpatch('\n'.join(patchlines), 'x-patch', opts.get('test'))
- binnode = bin(node)
- # if node is mq patch, it will have the patch file's name as a tag
- if not patchname:
- patchtags = [t for t in repo.nodetags(binnode)
- if t.endswith('.patch') or t.endswith('.diff')]
- if patchtags:
- patchname = patchtags[0]
- elif total > 1:
- patchname = cmdutil.make_filename(repo, '%b-%n.patch',
- binnode, seqno=idx, total=total)
- else:
- patchname = cmdutil.make_filename(repo, '%b.patch', binnode)
- disposition = 'inline'
- if opts.get('attach'):
- disposition = 'attachment'
- p['Content-Disposition'] = disposition + '; filename=' + patchname
- msg.attach(p)
- else:
- body += '\n'.join(patchlines)
- msg = mail.mimetextpatch(body, display=opts.get('test'))
-
- flag = ' '.join(opts.get('flag'))
- if flag:
- flag = ' ' + flag
-
- subj = desc[0].strip().rstrip('. ')
- if not introneeded(opts, total):
- subj = '[PATCH%s] %s' % (flag, opts.get('subject') or subj)
- else:
- tlen = len(str(total))
- subj = '[PATCH %0*d of %d%s] %s' % (tlen, idx, total, flag, subj)
- msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
- msg['X-Mercurial-Node'] = node
- return msg, subj, ds
-
-def patchbomb(ui, repo, *revs, **opts):
- '''send changesets by email
-
- By default, diffs are sent in the format generated by
- :hg:`export`, one per message. The series starts with a "[PATCH 0
- of N]" introduction, which describes the series as a whole.
-
- Each patch email has a Subject line of "[PATCH M of N] ...", using
- the first line of the changeset description as the subject text.
- The message contains two or three parts. First, the changeset
- description.
-
- With the -d/--diffstat option, if the diffstat program is
- installed, the result of running diffstat on the patch is inserted.
-
- Finally, the patch itself, as generated by :hg:`export`.
-
- With the -d/--diffstat or -c/--confirm options, you will be presented
- with a final summary of all messages and asked for confirmation before
- the messages are sent.
-
- By default the patch is included as text in the email body for
- easy reviewing. Using the -a/--attach option will instead create
- an attachment for the patch. With -i/--inline an inline attachment
- will be created.
-
- With -o/--outgoing, emails will be generated for patches not found
- in the destination repository (or only those which are ancestors
- of the specified revisions if any are provided)
-
- With -b/--bundle, changesets are selected as for --outgoing, but a
- single email containing a binary Mercurial bundle as an attachment
- will be sent.
-
- With -m/--mbox, instead of previewing each patchbomb message in a
- pager or sending the messages directly, it will create a UNIX
- mailbox file with the patch emails. This mailbox file can be
- previewed with any mail user agent which supports UNIX mbox
- files.
-
- With -n/--test, all steps will run, but mail will not be sent.
- You will be prompted for an email recipient address, a subject and
- an introductory message describing the patches of your patchbomb.
- Then when all is done, patchbomb messages are displayed. If the
- PAGER environment variable is set, your pager will be fired up once
- for each patchbomb message, so you can verify everything is alright.
-
- Examples::
-
- hg email -r 3000 # send patch 3000 only
- hg email -r 3000 -r 3001 # send patches 3000 and 3001
- hg email -r 3000:3005 # send patches 3000 through 3005
- hg email 3000 # send patch 3000 (deprecated)
-
- hg email -o # send all patches not in default
- hg email -o DEST # send all patches not in DEST
- hg email -o -r 3000 # send all ancestors of 3000 not in default
- hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST
-
- hg email -b # send bundle of all patches not in default
- hg email -b DEST # send bundle of all patches not in DEST
- hg email -b -r 3000 # bundle of all ancestors of 3000 not in default
- hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST
-
- hg email -o -m mbox && # generate an mbox file...
- mutt -R -f mbox # ... and view it with mutt
- hg email -o -m mbox && # generate an mbox file ...
- formail -s sendmail \\ # ... and use formail to send from the mbox
- -bm -t < mbox # ... using sendmail
-
- Before using this command, you will need to enable email in your
- hgrc. See the [email] section in hgrc(5) for details.
- '''
-
- _charsets = mail._charsets(ui)
-
- bundle = opts.get('bundle')
- date = opts.get('date')
- mbox = opts.get('mbox')
- outgoing = opts.get('outgoing')
- rev = opts.get('rev')
- # internal option used by pbranches
- patches = opts.get('patches')
-
- def getoutgoing(dest, revs):
- '''Return the revisions present locally but not in dest'''
- dest = ui.expandpath(dest or 'default-push', dest or 'default')
- dest, branches = hg.parseurl(dest)
- revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
- if revs:
- revs = [repo.lookup(rev) for rev in revs]
- other = hg.repository(hg.remoteui(repo, opts), dest)
- ui.status(_('comparing with %s\n') % url.hidepassword(dest))
- o = discovery.findoutgoing(repo, other)
- if not o:
- ui.status(_("no changes found\n"))
- return []
- o = repo.changelog.nodesbetween(o, revs)[0]
- return [str(repo.changelog.rev(r)) for r in o]
-
- def getpatches(revs):
- for r in cmdutil.revrange(repo, revs):
- output = cStringIO.StringIO()
- cmdutil.export(repo, [r], fp=output,
- opts=patch.diffopts(ui, opts))
- yield output.getvalue().split('\n')
-
- def getbundle(dest):
- tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-')
- tmpfn = os.path.join(tmpdir, 'bundle')
- try:
- commands.bundle(ui, repo, tmpfn, dest, **opts)
- return open(tmpfn, 'rb').read()
- finally:
- try:
- os.unlink(tmpfn)
- except:
- pass
- os.rmdir(tmpdir)
-
- if not (opts.get('test') or mbox):
- # really sending
- mail.validateconfig(ui)
-
- if not (revs or rev or outgoing or bundle or patches):
- raise util.Abort(_('specify at least one changeset with -r or -o'))
-
- if outgoing and bundle:
- raise util.Abort(_("--outgoing mode always on with --bundle;"
- " do not re-specify --outgoing"))
-
- if outgoing or bundle:
- if len(revs) > 1:
- raise util.Abort(_("too many destinations"))
- dest = revs and revs[0] or None
- revs = []
-
- if rev:
- if revs:
- raise util.Abort(_('use only one form to specify the revision'))
- revs = rev
-
- if outgoing:
- revs = getoutgoing(dest, rev)
- if bundle:
- opts['revs'] = revs
-
- # start
- if date:
- start_time = util.parsedate(date)
- else:
- start_time = util.makedate()
-
- def genmsgid(id):
- return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn())
-
- def getdescription(body, sender):
- if opts.get('desc'):
- body = open(opts.get('desc')).read()
- else:
- ui.write(_('\nWrite the introductory message for the '
- 'patch series.\n\n'))
- body = ui.edit(body, sender)
- return body
-
- def getpatchmsgs(patches, patchnames=None):
- jumbo = []
- msgs = []
-
- ui.write(_('This patch series consists of %d patches.\n\n')
- % len(patches))
-
- name = None
- for i, p in enumerate(patches):
- jumbo.extend(p)
- if patchnames:
- name = patchnames[i]
- msg = makepatch(ui, repo, p, opts, _charsets, i + 1,
- len(patches), name)
- msgs.append(msg)
-
- if introneeded(opts, len(patches)):
- tlen = len(str(len(patches)))
-
- flag = ' '.join(opts.get('flag'))
- if flag:
- subj = '[PATCH %0*d of %d %s]' % (tlen, 0, len(patches), flag)
- else:
- subj = '[PATCH %0*d of %d]' % (tlen, 0, len(patches))
- subj += ' ' + (opts.get('subject') or
- prompt(ui, 'Subject: ', rest=subj))
-
- body = ''
- ds = patch.diffstat(jumbo)
- if ds and opts.get('diffstat'):
- body = '\n' + ds
-
- body = getdescription(body, sender)
- msg = mail.mimeencode(ui, body, _charsets, opts.get('test'))
- msg['Subject'] = mail.headencode(ui, subj, _charsets,
- opts.get('test'))
-
- msgs.insert(0, (msg, subj, ds))
- return msgs
-
- def getbundlemsgs(bundle):
- subj = (opts.get('subject')
- or prompt(ui, 'Subject:', 'A bundle for your repository'))
-
- body = getdescription('', sender)
- msg = email.MIMEMultipart.MIMEMultipart()
- if body:
- msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test')))
- datapart = email.MIMEBase.MIMEBase('application', 'x-mercurial-bundle')
- datapart.set_payload(bundle)
- bundlename = '%s.hg' % opts.get('bundlename', 'bundle')
- datapart.add_header('Content-Disposition', 'attachment',
- filename=bundlename)
- email.Encoders.encode_base64(datapart)
- msg.attach(datapart)
- msg['Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test'))
- return [(msg, subj, None)]
-
- sender = (opts.get('from') or ui.config('email', 'from') or
- ui.config('patchbomb', 'from') or
- prompt(ui, 'From', ui.username()))
-
- if patches:
- msgs = getpatchmsgs(patches, opts.get('patchnames'))
- elif bundle:
- msgs = getbundlemsgs(getbundle(dest))
- else:
- msgs = getpatchmsgs(list(getpatches(revs)))
-
- showaddrs = []
-
- def getaddrs(opt, prpt=None, default=None):
- addrs = opts.get(opt.replace('-', '_'))
- if opt != 'reply-to':
- showaddr = '%s:' % opt.capitalize()
- else:
- showaddr = 'Reply-To:'
-
- if addrs:
- showaddrs.append('%s %s' % (showaddr, ', '.join(addrs)))
- return mail.addrlistencode(ui, addrs, _charsets, opts.get('test'))
-
- addrs = ui.config('email', opt) or ui.config('patchbomb', opt) or ''
- if not addrs and prpt:
- addrs = prompt(ui, prpt, default)
-
- if addrs:
- showaddrs.append('%s %s' % (showaddr, addrs))
- return mail.addrlistencode(ui, [addrs], _charsets, opts.get('test'))
-
- to = getaddrs('to', 'To')
- cc = getaddrs('cc', 'Cc', '')
- bcc = getaddrs('bcc')
- replyto = getaddrs('reply-to')
-
- if opts.get('diffstat') or opts.get('confirm'):
- ui.write(_('\nFinal summary:\n\n'))
- ui.write('From: %s\n' % sender)
- for addr in showaddrs:
- ui.write('%s\n' % addr)
- for m, subj, ds in msgs:
- ui.write('Subject: %s\n' % subj)
- if ds:
- ui.write(ds)
- ui.write('\n')
- if ui.promptchoice(_('are you sure you want to send (yn)?'),
- (_('&Yes'), _('&No'))):
- raise util.Abort(_('patchbomb canceled'))
-
- ui.write('\n')
-
- parent = opts.get('in_reply_to') or None
- # angle brackets may be omitted, they're not semantically part of the msg-id
- if parent is not None:
- if not parent.startswith('<'):
- parent = '<' + parent
- if not parent.endswith('>'):
- parent += '>'
-
- first = True
-
- sender_addr = email.Utils.parseaddr(sender)[1]
- sender = mail.addressencode(ui, sender, _charsets, opts.get('test'))
- sendmail = None
- for i, (m, subj, ds) in enumerate(msgs):
- try:
- m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
- except TypeError:
- m['Message-Id'] = genmsgid('patchbomb')
- if parent:
- m['In-Reply-To'] = parent
- m['References'] = parent
- if first:
- parent = m['Message-Id']
- first = False
-
- m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version()
- m['Date'] = email.Utils.formatdate(start_time[0], localtime=True)
-
- start_time = (start_time[0] + 1, start_time[1])
- m['From'] = sender
- m['To'] = ', '.join(to)
- if cc:
- m['Cc'] = ', '.join(cc)
- if bcc:
- m['Bcc'] = ', '.join(bcc)
- if replyto:
- m['Reply-To'] = ', '.join(replyto)
- if opts.get('test'):
- ui.status(_('Displaying '), subj, ' ...\n')
- ui.flush()
- if 'PAGER' in os.environ and not ui.plain():
- fp = util.popen(os.environ['PAGER'], 'w')
- else:
- fp = ui
- generator = email.Generator.Generator(fp, mangle_from_=False)
- try:
- generator.flatten(m, 0)
- fp.write('\n')
- except IOError, inst:
- if inst.errno != errno.EPIPE:
- raise
- if fp is not ui:
- fp.close()
- elif mbox:
- ui.status(_('Writing '), subj, ' ...\n')
- ui.progress(_('writing'), i, item=subj, total=len(msgs))
- fp = open(mbox, 'In-Reply-To' in m and 'ab+' or 'wb+')
- generator = email.Generator.Generator(fp, mangle_from_=True)
- # Should be time.asctime(), but Windows prints 2-characters day
- # of month instead of one. Make them print the same thing.
- date = time.strftime('%a %b %d %H:%M:%S %Y',
- time.localtime(start_time[0]))
- fp.write('From %s %s\n' % (sender_addr, date))
- generator.flatten(m, 0)
- fp.write('\n\n')
- fp.close()
- else:
- if not sendmail:
- sendmail = mail.connect(ui)
- ui.status(_('Sending '), subj, ' ...\n')
- ui.progress(_('sending'), i, item=subj, total=len(msgs))
- # Exim does not remove the Bcc field
- del m['Bcc']
- fp = cStringIO.StringIO()
- generator = email.Generator.Generator(fp, mangle_from_=False)
- generator.flatten(m, 0)
- sendmail(sender, to + bcc + cc, fp.getvalue())
-
- ui.progress(_('writing'), None)
- ui.progress(_('sending'), None)
-
-emailopts = [
- ('a', 'attach', None, _('send patches as attachments')),
- ('i', 'inline', None, _('send patches as inline attachments')),
- ('', 'bcc', [], _('email addresses of blind carbon copy recipients')),
- ('c', 'cc', [], _('email addresses of copy recipients')),
- ('', 'confirm', None, _('ask for confirmation before sending')),
- ('d', 'diffstat', None, _('add diffstat output to messages')),
- ('', 'date', '', _('use the given date as the sending date')),
- ('', 'desc', '', _('use the given file as the series description')),
- ('f', 'from', '', _('email address of sender')),
- ('n', 'test', None, _('print messages that would be sent')),
- ('m', 'mbox', '',
- _('write messages to mbox file instead of sending them')),
- ('', 'reply-to', [], _('email addresses replies should be sent to')),
- ('s', 'subject', '',
- _('subject of first message (intro or single patch)')),
- ('', 'in-reply-to', '',
- _('message identifier to reply to')),
- ('', 'flag', [], _('flags to add in subject prefixes')),
- ('t', 'to', [], _('email addresses of recipients')),
- ]
-
-
-cmdtable = {
- "email":
- (patchbomb,
- [('g', 'git', None, _('use git extended diff format')),
- ('', 'plain', None, _('omit hg patch header')),
- ('o', 'outgoing', None,
- _('send changes not found in the target repository')),
- ('b', 'bundle', None,
- _('send changes not in target as a binary bundle')),
- ('', 'bundlename', 'bundle',
- _('name of the bundle attachment file'), _('NAME')),
- ('r', 'rev', [],
- _('a revision to send'), _('REV')),
- ('', 'force', None,
- _('run even when remote repository is unrelated '
- '(with -b/--bundle)')),
- ('', 'base', [],
- _('a base changeset to specify instead of a destination '
- '(with -b/--bundle)'),
- _('REV')),
- ('', 'intro', None,
- _('send an introduction email for a single patch')),
- ] + emailopts + commands.remoteopts,
- _('hg email [OPTION]... [DEST]...'))
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.pyo
deleted file mode 100644
index 57d9f7f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/patchbomb.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.py
deleted file mode 100644
index e25f4f8..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# progress.py show progress bars for some actions
-#
-# Copyright (C) 2010 Augie Fackler <durin42@gmail.com>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-"""show progress bars for some actions
-
-This extension uses the progress information logged by hg commands
-to draw progress bars that are as informative as possible. Some progress
-bars only offer indeterminate information, while others have a definite
-end point.
-
-The following settings are available::
-
- [progress]
- delay = 3 # number of seconds (float) before showing the progress bar
- refresh = 0.1 # time in seconds between refreshes of the progress bar
- format = topic bar number # format of the progress bar
- width = <none> # if set, the maximum width of the progress information
- # (that is, min(width, term width) will be used)
- clear-complete = True # clear the progress bar after it's done
- disable = False # if true, don't show a progress bar
- assume-tty = False # if true, ALWAYS show a progress bar, unless
- # disable is given
-
-Valid entries for the format field are topic, bar, number, unit, and
-item. item defaults to the last 20 characters of the item, but this
-can be changed by adding either ``-<num>`` which would take the last
-num characters, or ``+<num>`` for the first num characters.
-"""
-
-import sys
-import time
-
-from mercurial import util
-
-def spacejoin(*args):
- return ' '.join(s for s in args if s)
-
-def shouldprint(ui):
- return (getattr(sys.stderr, 'isatty', None) and
- (sys.stderr.isatty() or ui.configbool('progress', 'assume-tty')))
-
-class progbar(object):
- def __init__(self, ui):
- self.ui = ui
- self.resetstate()
-
- def resetstate(self):
- self.topics = []
- self.printed = False
- self.lastprint = time.time() + float(self.ui.config(
- 'progress', 'delay', default=3))
- self.indetcount = 0
- self.refresh = float(self.ui.config(
- 'progress', 'refresh', default=0.1))
- self.order = self.ui.configlist(
- 'progress', 'format',
- default=['topic', 'bar', 'number'])
-
- def show(self, topic, pos, item, unit, total):
- if not shouldprint(self.ui):
- return
- termwidth = self.width()
- self.printed = True
- head = ''
- needprogress = False
- tail = ''
- for indicator in self.order:
- add = ''
- if indicator == 'topic':
- add = topic
- elif indicator == 'number':
- if total:
- add = ('% ' + str(len(str(total))) +
- 's/%s') % (pos, total)
- else:
- add = str(pos)
- elif indicator.startswith('item') and item:
- slice = 'end'
- if '-' in indicator:
- wid = int(indicator.split('-')[1])
- elif '+' in indicator:
- slice = 'beginning'
- wid = int(indicator.split('+')[1])
- else:
- wid = 20
- if slice == 'end':
- add = item[-wid:]
- else:
- add = item[:wid]
- add += (wid - len(add)) * ' '
- elif indicator == 'bar':
- add = ''
- needprogress = True
- elif indicator == 'unit' and unit:
- add = unit
- if not needprogress:
- head = spacejoin(head, add)
- else:
- tail = spacejoin(add, tail)
- if needprogress:
- used = 0
- if head:
- used += len(head) + 1
- if tail:
- used += len(tail) + 1
- progwidth = termwidth - used - 3
- if total and pos <= total:
- amt = pos * progwidth // total
- bar = '=' * (amt - 1)
- if amt > 0:
- bar += '>'
- bar += ' ' * (progwidth - amt)
- else:
- progwidth -= 3
- self.indetcount += 1
- # mod the count by twice the width so we can make the
- # cursor bounce between the right and left sides
- amt = self.indetcount % (2 * progwidth)
- amt -= progwidth
- bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
- ' ' * int(abs(amt)))
- prog = ''.join(('[', bar , ']'))
- out = spacejoin(head, prog, tail)
- else:
- out = spacejoin(head, tail)
- sys.stderr.write('\r' + out[:termwidth])
- sys.stderr.flush()
-
- def clear(self):
- if not shouldprint(self.ui):
- return
- sys.stderr.write('\r%s\r' % (' ' * self.width()))
-
- def complete(self):
- if not shouldprint(self.ui):
- return
- if self.ui.configbool('progress', 'clear-complete', default=True):
- self.clear()
- else:
- sys.stderr.write('\n')
- sys.stderr.flush()
-
- def width(self):
- tw = self.ui.termwidth()
- return min(int(self.ui.config('progress', 'width', default=tw)), tw)
-
- def progress(self, topic, pos, item='', unit='', total=None):
- if pos is None:
- if self.topics and self.topics[-1] == topic and self.printed:
- self.complete()
- self.resetstate()
- else:
- if topic not in self.topics:
- self.topics.append(topic)
- now = time.time()
- if (now - self.lastprint >= self.refresh
- and topic == self.topics[-1]):
- self.lastprint = now
- self.show(topic, pos, item, unit, total)
-
-def uisetup(ui):
- class progressui(ui.__class__):
- _progbar = None
-
- def progress(self, *args, **opts):
- self._progbar.progress(*args, **opts)
- return super(progressui, self).progress(*args, **opts)
-
- def write(self, *args, **opts):
- if self._progbar.printed:
- self._progbar.clear()
- return super(progressui, self).write(*args, **opts)
-
- def write_err(self, *args, **opts):
- if self._progbar.printed:
- self._progbar.clear()
- return super(progressui, self).write_err(*args, **opts)
-
- # Apps that derive a class from ui.ui() can use
- # setconfig('progress', 'disable', 'True') to disable this extension
- if ui.configbool('progress', 'disable'):
- return
- if shouldprint(ui) and not ui.debugflag and not ui.quiet:
- ui.__class__ = progressui
- # we instantiate one globally shared progress bar to avoid
- # competing progress bars when multiple UI objects get created
- if not progressui._progbar:
- progressui._progbar = progbar(ui)
-
-def reposetup(ui, repo):
- uisetup(repo.ui)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.pyo
deleted file mode 100644
index e0a83d4..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/progress.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.py
deleted file mode 100644
index 4a99ec3..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (C) 2006 - Marco Barisione <marco@barisione.org>
-#
-# This is a small extension for Mercurial (http://mercurial.selenic.com/)
-# that removes files not known to mercurial
-#
-# This program was inspired by the "cvspurge" script contained in CVS
-# utilities (http://www.red-bean.com/cvsutils/).
-#
-# For help on the usage of "hg purge" use:
-# hg help purge
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-'''command to delete untracked files from the working directory'''
-
-from mercurial import util, commands, cmdutil
-from mercurial.i18n import _
-import os, stat
-
-def purge(ui, repo, *dirs, **opts):
- '''removes files not tracked by Mercurial
-
- Delete files not known to Mercurial. This is useful to test local
- and uncommitted changes in an otherwise-clean source tree.
-
- This means that purge will delete:
-
- - Unknown files: files marked with "?" by :hg:`status`
- - Empty directories: in fact Mercurial ignores directories unless
- they contain files under source control management
-
- But it will leave untouched:
-
- - Modified and unmodified tracked files
- - Ignored files (unless --all is specified)
- - New files added to the repository (with :hg:`add`)
-
- If directories are given on the command line, only files in these
- directories are considered.
-
- Be careful with purge, as you could irreversibly delete some files
- you forgot to add to the repository. If you only want to print the
- list of files that this program would delete, use the --print
- option.
- '''
- act = not opts['print']
- eol = '\n'
- if opts['print0']:
- eol = '\0'
- act = False # --print0 implies --print
-
- def remove(remove_func, name):
- if act:
- try:
- remove_func(repo.wjoin(name))
- except OSError:
- 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))
-
- def removefile(path):
- try:
- os.remove(path)
- except OSError:
- # 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)
-
- directories = []
- match = cmdutil.match(repo, dirs, opts)
- match.dir = directories.append
- status = repo.status(match=match, ignored=opts['all'], unknown=True)
-
- for f in sorted(status[4] + status[5]):
- ui.note(_('Removing file %s\n') % f)
- remove(removefile, f)
-
- for f in sorted(directories, reverse=True):
- if match(f) and not os.listdir(repo.wjoin(f)):
- ui.note(_('Removing directory %s\n') % f)
- remove(os.rmdir, f)
-
-cmdtable = {
- 'purge|clean':
- (purge,
- [('a', 'abort-on-err', None, _('abort if an error occurs')),
- ('', 'all', None, _('purge ignored files too')),
- ('p', 'print', None, _('print filenames instead of deleting them')),
- ('0', 'print0', None, _('end filenames with NUL, for use with xargs'
- ' (implies -p/--print)')),
- ] + commands.walkopts,
- _('hg purge [OPTION]... [DIR]...'))
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.pyo
deleted file mode 100644
index 69287ba..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/purge.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.py
deleted file mode 100644
index 7a43541..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.py
+++ /dev/null
@@ -1,577 +0,0 @@
-# rebase.py - rebasing feature for mercurial
-#
-# Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to move sets of revisions to a different ancestor
-
-This extension lets you rebase changesets in an existing Mercurial
-repository.
-
-For more information:
-http://mercurial.selenic.com/wiki/RebaseExtension
-'''
-
-from mercurial import hg, util, repair, merge, cmdutil, commands
-from mercurial import extensions, ancestor, copies, patch
-from mercurial.commands import templateopts
-from mercurial.node import nullrev
-from mercurial.lock import release
-from mercurial.i18n import _
-import os, errno
-
-nullmerge = -2
-
-def rebase(ui, repo, **opts):
- """move changeset (and descendants) to a different branch
-
- Rebase uses repeated merging to graft changesets from one part of
- history (the source) onto another (the destination). This can be
- useful for linearizing *local* changes relative to a master
- development tree.
-
- You should not rebase changesets that have already been shared
- with others. Doing so will force everybody else to perform the
- same rebase or they will end up with duplicated changesets after
- pulling in your rebased changesets.
-
- If you don't specify a destination changeset (``-d/--dest``),
- rebase uses the tipmost head of the current named branch as the
- destination. (The destination changeset is not modified by
- rebasing, but new changesets are added as its descendants.)
-
- You can specify which changesets to rebase in two ways: as a
- "source" changeset or as a "base" changeset. Both are shorthand
- for a topologically related set of changesets (the "source
- branch"). If you specify source (``-s/--source``), rebase will
- rebase that changeset and all of its descendants onto dest. If you
- specify base (``-b/--base``), rebase will select ancestors of base
- back to but not including the common ancestor with dest. Thus,
- ``-b`` is less precise but more convenient than ``-s``: you can
- specify any changeset in the source branch, and rebase will select
- the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
- uses the parent of the working directory as the base.
-
- By default, rebase recreates the changesets in the source branch
- as descendants of dest and then destroys the originals. Use
- ``--keep`` to preserve the original source changesets. Some
- changesets in the source branch (e.g. merges from the destination
- branch) may be dropped if they no longer contribute any change.
-
- One result of the rules for selecting the destination changeset
- and source branch is that, unlike ``merge``, rebase will do
- nothing if you are at the latest (tipmost) head of a named branch
- with two heads. You need to explicitly specify source and/or
- destination (or ``update`` to the other head, if it's the head of
- the intended source branch).
-
- If a rebase is interrupted to manually resolve a merge, it can be
- continued with --continue/-c or aborted with --abort/-a.
-
- Returns 0 on success, 1 if nothing to rebase.
- """
- originalwd = target = None
- external = nullrev
- state = {}
- skipped = set()
- targetancestors = set()
-
- lock = wlock = None
- try:
- lock = repo.lock()
- wlock = repo.wlock()
-
- # Validate input and define rebasing points
- destf = opts.get('dest', None)
- srcf = opts.get('source', None)
- basef = opts.get('base', None)
- contf = opts.get('continue')
- abortf = opts.get('abort')
- collapsef = opts.get('collapse', False)
- extrafn = opts.get('extrafn')
- keepf = opts.get('keep', False)
- keepbranchesf = opts.get('keepbranches', False)
- detachf = opts.get('detach', False)
- # keepopen is not meant for use on the command line, but by
- # other extensions
- keepopen = opts.get('keepopen', False)
-
- if contf or abortf:
- if contf and abortf:
- raise util.Abort(_('cannot use both abort and continue'))
- if collapsef:
- raise util.Abort(
- _('cannot use collapse with continue or abort'))
- if detachf:
- raise util.Abort(_('cannot use detach with continue or abort'))
- if srcf or basef or destf:
- raise util.Abort(
- _('abort and continue do not allow specifying revisions'))
-
- (originalwd, target, state, skipped, collapsef, keepf,
- keepbranchesf, external) = restorestatus(repo)
- if abortf:
- return abort(repo, originalwd, target, state)
- else:
- if srcf and basef:
- raise util.Abort(_('cannot specify both a '
- 'revision and a base'))
- if detachf:
- if not srcf:
- raise util.Abort(
- _('detach requires a revision to be specified'))
- if basef:
- raise util.Abort(_('cannot specify a base with detach'))
-
- cmdutil.bail_if_changed(repo)
- result = buildstate(repo, destf, srcf, basef, detachf)
- if not result:
- # Empty state built, nothing to rebase
- ui.status(_('nothing to rebase\n'))
- return 1
- else:
- originalwd, target, state = result
- if collapsef:
- targetancestors = set(repo.changelog.ancestors(target))
- external = checkexternal(repo, state, targetancestors)
-
- if keepbranchesf:
- if extrafn:
- raise util.Abort(_('cannot use both keepbranches and extrafn'))
- def extrafn(ctx, extra):
- extra['branch'] = ctx.branch()
-
- # Rebase
- if not targetancestors:
- targetancestors = set(repo.changelog.ancestors(target))
- targetancestors.add(target)
-
- sortedstate = sorted(state)
- total = len(sortedstate)
- pos = 0
- for rev in sortedstate:
- pos += 1
- if state[rev] == -1:
- ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
- _('changesets'), total)
- storestatus(repo, originalwd, target, state, collapsef, keepf,
- keepbranchesf, external)
- p1, p2 = defineparents(repo, rev, target, state,
- targetancestors)
- if len(repo.parents()) == 2:
- repo.ui.debug('resuming interrupted rebase\n')
- else:
- stats = rebasenode(repo, rev, p1, p2, state)
- if stats and stats[3] > 0:
- raise util.Abort(_('unresolved conflicts (see hg '
- 'resolve, then hg rebase --continue)'))
- updatedirstate(repo, rev, target, p2)
- if not collapsef:
- newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn)
- else:
- # Skip commit if we are collapsing
- repo.dirstate.setparents(repo[p1].node())
- newrev = None
- # Update the state
- if newrev is not None:
- state[rev] = repo[newrev].rev()
- else:
- if not collapsef:
- ui.note(_('no changes, revision %d skipped\n') % rev)
- ui.debug('next revision set to %s\n' % p1)
- skipped.add(rev)
- state[rev] = p1
-
- ui.progress(_('rebasing'), None)
- ui.note(_('rebase merging completed\n'))
-
- if collapsef and not keepopen:
- p1, p2 = defineparents(repo, min(state), target,
- state, targetancestors)
- commitmsg = 'Collapsed revision'
- for rebased in state:
- if rebased not in skipped and state[rebased] != nullmerge:
- commitmsg += '\n* %s' % repo[rebased].description()
- commitmsg = ui.edit(commitmsg, repo.ui.username())
- newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
- extrafn=extrafn)
-
- if 'qtip' in repo.tags():
- updatemq(repo, state, skipped, **opts)
-
- if not keepf:
- # Remove no more useful revisions
- rebased = [rev for rev in state if state[rev] != nullmerge]
- if rebased:
- if set(repo.changelog.descendants(min(rebased))) - set(state):
- ui.warn(_("warning: new changesets detected "
- "on source branch, not stripping\n"))
- else:
- # backup the old csets by default
- repair.strip(ui, repo, repo[min(rebased)].node(), "all")
-
- clearstatus(repo)
- ui.note(_("rebase completed\n"))
- if os.path.exists(repo.sjoin('undo')):
- util.unlink(repo.sjoin('undo'))
- if skipped:
- ui.note(_("%d revisions have been skipped\n") % len(skipped))
- finally:
- release(lock, wlock)
-
-def rebasemerge(repo, rev, first=False):
- 'return the correct ancestor'
- oldancestor = ancestor.ancestor
-
- def newancestor(a, b, pfunc):
- if b == rev:
- return repo[rev].parents()[0].rev()
- return oldancestor(a, b, pfunc)
-
- if not first:
- ancestor.ancestor = newancestor
- else:
- repo.ui.debug("first revision, do not change ancestor\n")
- try:
- stats = merge.update(repo, rev, True, True, False)
- return stats
- finally:
- ancestor.ancestor = oldancestor
-
-def checkexternal(repo, state, targetancestors):
- """Check whether one or more external revisions need to be taken in
- consideration. In the latter case, abort.
- """
- external = nullrev
- source = min(state)
- for rev in state:
- if rev == source:
- continue
- # Check externals and fail if there are more than one
- for p in repo[rev].parents():
- if (p.rev() not in state
- and p.rev() not in targetancestors):
- if external != nullrev:
- raise util.Abort(_('unable to collapse, there is more '
- 'than one external parent'))
- external = p.rev()
- return external
-
-def updatedirstate(repo, rev, p1, p2):
- """Keep track of renamed files in the revision that is going to be rebased
- """
- # Here we simulate the copies and renames in the source changeset
- cop, diver = copies.copies(repo, repo[rev], repo[p1], repo[p2], True)
- m1 = repo[rev].manifest()
- m2 = repo[p1].manifest()
- for k, v in cop.iteritems():
- if k in m1:
- if v in m1 or v in m2:
- repo.dirstate.copy(v, k)
- if v in m2 and v not in m1:
- repo.dirstate.remove(v)
-
-def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
- 'Commit the changes and store useful information in extra'
- try:
- repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
- ctx = repo[rev]
- if commitmsg is None:
- commitmsg = ctx.description()
- extra = {'rebase_source': ctx.hex()}
- if extrafn:
- extrafn(ctx, extra)
- # Commit might fail if unresolved files exist
- newrev = repo.commit(text=commitmsg, user=ctx.user(),
- date=ctx.date(), extra=extra)
- repo.dirstate.setbranch(repo[newrev].branch())
- return newrev
- except util.Abort:
- # Invalidate the previous setparents
- repo.dirstate.invalidate()
- raise
-
-def rebasenode(repo, rev, p1, p2, state):
- 'Rebase a single revision'
- # Merge phase
- # Update to target and merge it with local
- if repo['.'].rev() != repo[p1].rev():
- repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
- merge.update(repo, p1, False, True, False)
- else:
- repo.ui.debug(" already in target\n")
- repo.dirstate.write()
- repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
- first = repo[rev].rev() == repo[min(state)].rev()
- stats = rebasemerge(repo, rev, first)
- return stats
-
-def defineparents(repo, rev, target, state, targetancestors):
- 'Return the new parent relationship of the revision that will be rebased'
- parents = repo[rev].parents()
- p1 = p2 = nullrev
-
- P1n = parents[0].rev()
- if P1n in targetancestors:
- p1 = target
- elif P1n in state:
- if state[P1n] == nullmerge:
- p1 = target
- else:
- p1 = state[P1n]
- else: # P1n external
- p1 = target
- p2 = P1n
-
- if len(parents) == 2 and parents[1].rev() not in targetancestors:
- P2n = parents[1].rev()
- # interesting second parent
- if P2n in state:
- if p1 == target: # P1n in targetancestors or external
- p1 = state[P2n]
- else:
- p2 = state[P2n]
- else: # P2n external
- if p2 != nullrev: # P1n external too => rev is a merged revision
- raise util.Abort(_('cannot use revision %d as base, result '
- 'would have 3 parents') % rev)
- p2 = P2n
- repo.ui.debug(" future parents are %d and %d\n" %
- (repo[p1].rev(), repo[p2].rev()))
- return p1, p2
-
-def isagitpatch(repo, patchname):
- 'Return true if the given patch is in git format'
- mqpatch = os.path.join(repo.mq.path, patchname)
- for line in patch.linereader(file(mqpatch, 'rb')):
- if line.startswith('diff --git'):
- return True
- return False
-
-def updatemq(repo, state, skipped, **opts):
- 'Update rebased mq patches - finalize and then import them'
- mqrebase = {}
- mq = repo.mq
- for p in mq.applied:
- rev = repo[p.node].rev()
- if rev in state:
- repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
- (rev, p.name))
- mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
-
- if mqrebase:
- mq.finish(repo, mqrebase.keys())
-
- # We must start import from the newest revision
- for rev in sorted(mqrebase, reverse=True):
- if rev not in skipped:
- name, isgit = mqrebase[rev]
- repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
- mq.qimport(repo, (), patchname=name, git=isgit,
- rev=[str(state[rev])])
- mq.save_dirty()
-
-def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
- external):
- 'Store the current status to allow recovery'
- f = repo.opener("rebasestate", "w")
- f.write(repo[originalwd].hex() + '\n')
- f.write(repo[target].hex() + '\n')
- f.write(repo[external].hex() + '\n')
- f.write('%d\n' % int(collapse))
- f.write('%d\n' % int(keep))
- f.write('%d\n' % int(keepbranches))
- for d, v in state.iteritems():
- oldrev = repo[d].hex()
- newrev = repo[v].hex()
- f.write("%s:%s\n" % (oldrev, newrev))
- f.close()
- repo.ui.debug('rebase status stored\n')
-
-def clearstatus(repo):
- 'Remove the status files'
- if os.path.exists(repo.join("rebasestate")):
- util.unlink(repo.join("rebasestate"))
-
-def restorestatus(repo):
- 'Restore a previously stored status'
- try:
- target = None
- collapse = False
- external = nullrev
- state = {}
- f = repo.opener("rebasestate")
- for i, l in enumerate(f.read().splitlines()):
- if i == 0:
- originalwd = repo[l].rev()
- elif i == 1:
- target = repo[l].rev()
- elif i == 2:
- external = repo[l].rev()
- elif i == 3:
- collapse = bool(int(l))
- elif i == 4:
- keep = bool(int(l))
- elif i == 5:
- keepbranches = bool(int(l))
- else:
- oldrev, newrev = l.split(':')
- state[repo[oldrev].rev()] = repo[newrev].rev()
- skipped = set()
- # recompute the set of skipped revs
- if not collapse:
- seen = set([target])
- for old, new in sorted(state.items()):
- if new != nullrev and new in seen:
- skipped.add(old)
- seen.add(new)
- repo.ui.debug('computed skipped revs: %s\n' % skipped)
- repo.ui.debug('rebase status resumed\n')
- return (originalwd, target, state, skipped,
- collapse, keep, keepbranches, external)
- except IOError, err:
- if err.errno != errno.ENOENT:
- raise
- raise util.Abort(_('no rebase in progress'))
-
-def abort(repo, originalwd, target, state):
- 'Restore the repository to its original state'
- if set(repo.changelog.descendants(target)) - set(state.values()):
- repo.ui.warn(_("warning: new changesets detected on target branch, "
- "can't abort\n"))
- return -1
- else:
- # Strip from the first rebased revision
- merge.update(repo, repo[originalwd].rev(), False, True, False)
- rebased = filter(lambda x: x > -1 and x != target, state.values())
- if rebased:
- strippoint = min(rebased)
- # no backup of rebased cset versions needed
- repair.strip(repo.ui, repo, repo[strippoint].node())
- clearstatus(repo)
- repo.ui.warn(_('rebase aborted\n'))
- return 0
-
-def buildstate(repo, dest, src, base, detach):
- 'Define which revisions are going to be rebased and where'
- targetancestors = set()
- detachset = set()
-
- if not dest:
- # Destination defaults to the latest revision in the current branch
- branch = repo[None].branch()
- dest = repo[branch].rev()
- else:
- dest = repo[dest].rev()
-
- # This check isn't strictly necessary, since mq detects commits over an
- # applied patch. But it prevents messing up the working directory when
- # a partially completed rebase is blocked by mq.
- if 'qtip' in repo.tags() and (repo[dest].node() in
- [s.node for s in repo.mq.applied]):
- raise util.Abort(_('cannot rebase onto an applied mq patch'))
-
- if src:
- commonbase = repo[src].ancestor(repo[dest])
- if commonbase == repo[src]:
- raise util.Abort(_('source is ancestor of destination'))
- if commonbase == repo[dest]:
- raise util.Abort(_('source is descendant of destination'))
- source = repo[src].rev()
- if detach:
- # We need to keep track of source's ancestors up to the common base
- srcancestors = set(repo.changelog.ancestors(source))
- baseancestors = set(repo.changelog.ancestors(commonbase.rev()))
- detachset = srcancestors - baseancestors
- detachset.discard(commonbase.rev())
- else:
- if base:
- cwd = repo[base].rev()
- else:
- cwd = repo['.'].rev()
-
- if cwd == dest:
- repo.ui.debug('source and destination are the same\n')
- return None
-
- targetancestors = set(repo.changelog.ancestors(dest))
- if cwd in targetancestors:
- repo.ui.debug('source is ancestor of destination\n')
- return None
-
- cwdancestors = set(repo.changelog.ancestors(cwd))
- if dest in cwdancestors:
- repo.ui.debug('source is descendant of destination\n')
- return None
-
- cwdancestors.add(cwd)
- rebasingbranch = cwdancestors - targetancestors
- source = min(rebasingbranch)
-
- repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
- state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
- state.update(dict.fromkeys(detachset, nullmerge))
- state[source] = nullrev
- return repo['.'].rev(), repo[dest].rev(), state
-
-def pullrebase(orig, ui, repo, *args, **opts):
- 'Call rebase after pull if the latter has been invoked with --rebase'
- if opts.get('rebase'):
- if opts.get('update'):
- del opts['update']
- ui.debug('--update and --rebase are not compatible, ignoring '
- 'the update flag\n')
-
- cmdutil.bail_if_changed(repo)
- revsprepull = len(repo)
- origpostincoming = commands.postincoming
- def _dummy(*args, **kwargs):
- pass
- commands.postincoming = _dummy
- try:
- orig(ui, repo, *args, **opts)
- finally:
- commands.postincoming = origpostincoming
- revspostpull = len(repo)
- if revspostpull > revsprepull:
- rebase(ui, repo, **opts)
- branch = repo[None].branch()
- dest = repo[branch].rev()
- if dest != repo['.'].rev():
- # there was nothing to rebase we force an update
- hg.update(repo, dest)
- else:
- orig(ui, repo, *args, **opts)
-
-def uisetup(ui):
- 'Replace pull with a decorator to provide --rebase option'
- entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
- entry[1].append(('', 'rebase', None,
- _("rebase working directory to branch head"))
-)
-
-cmdtable = {
-"rebase":
- (rebase,
- [
- ('s', 'source', '',
- _('rebase from the specified changeset'), _('REV')),
- ('b', 'base', '',
- _('rebase from the base of the specified changeset '
- '(up to greatest common ancestor of base and dest)'),
- _('REV')),
- ('d', 'dest', '',
- _('rebase onto the specified changeset'), _('REV')),
- ('', 'collapse', False, _('collapse the rebased changesets')),
- ('', 'keep', False, _('keep original changesets')),
- ('', 'keepbranches', False, _('keep original branch names')),
- ('', 'detach', False, _('force detaching of source from its original '
- 'branch')),
- ('c', 'continue', False, _('continue an interrupted rebase')),
- ('a', 'abort', False, _('abort an interrupted rebase'))] +
- templateopts,
- _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
- 'hg rebase {-a|-c}'))
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.pyo
deleted file mode 100644
index c637b8f..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/rebase.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.py
deleted file mode 100644
index c515c26..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.py
+++ /dev/null
@@ -1,569 +0,0 @@
-# record.py
-#
-# Copyright 2007 Bryan O'Sullivan <bos@serpentine.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''commands to interactively select changes for commit/qrefresh'''
-
-from mercurial.i18n import gettext, _
-from mercurial import cmdutil, commands, extensions, hg, mdiff, patch
-from mercurial import util
-import copy, cStringIO, errno, os, re, tempfile
-
-lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
-
-def scanpatch(fp):
- """like patch.iterhunks, but yield different events
-
- - ('file', [header_lines + fromfile + tofile])
- - ('context', [context_lines])
- - ('hunk', [hunk_lines])
- - ('range', (-start,len, +start,len, diffp))
- """
- lr = patch.linereader(fp)
-
- def scanwhile(first, p):
- """scan lr while predicate holds"""
- lines = [first]
- while True:
- line = lr.readline()
- if not line:
- break
- if p(line):
- lines.append(line)
- else:
- lr.push(line)
- break
- return lines
-
- while True:
- line = lr.readline()
- if not line:
- break
- if line.startswith('diff --git a/'):
- def notheader(line):
- s = line.split(None, 1)
- return not s or s[0] not in ('---', 'diff')
- header = scanwhile(line, notheader)
- fromfile = lr.readline()
- if fromfile.startswith('---'):
- tofile = lr.readline()
- header += [fromfile, tofile]
- else:
- lr.push(fromfile)
- yield 'file', header
- elif line[0] == ' ':
- yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
- elif line[0] in '-+':
- yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
- else:
- m = lines_re.match(line)
- if m:
- yield 'range', m.groups()
- else:
- raise patch.PatchError('unknown patch content: %r' % line)
-
-class header(object):
- """patch header
-
- XXX shoudn't we move this to mercurial/patch.py ?
- """
- diff_re = re.compile('diff --git a/(.*) b/(.*)$')
- allhunks_re = re.compile('(?:index|new file|deleted file) ')
- pretty_re = re.compile('(?:new file|deleted file) ')
- special_re = re.compile('(?:index|new|deleted|copy|rename) ')
-
- def __init__(self, header):
- self.header = header
- self.hunks = []
-
- def binary(self):
- for h in self.header:
- if h.startswith('index '):
- return True
-
- def pretty(self, fp):
- for h in self.header:
- if h.startswith('index '):
- fp.write(_('this modifies a binary file (all or nothing)\n'))
- break
- if self.pretty_re.match(h):
- fp.write(h)
- if self.binary():
- fp.write(_('this is a binary file\n'))
- break
- if h.startswith('---'):
- fp.write(_('%d hunks, %d lines changed\n') %
- (len(self.hunks),
- sum([max(h.added, h.removed) for h in self.hunks])))
- break
- fp.write(h)
-
- def write(self, fp):
- fp.write(''.join(self.header))
-
- def allhunks(self):
- for h in self.header:
- if self.allhunks_re.match(h):
- return True
-
- def files(self):
- fromfile, tofile = self.diff_re.match(self.header[0]).groups()
- if fromfile == tofile:
- return [fromfile]
- return [fromfile, tofile]
-
- def filename(self):
- return self.files()[-1]
-
- def __repr__(self):
- return '<header %s>' % (' '.join(map(repr, self.files())))
-
- def special(self):
- for h in self.header:
- if self.special_re.match(h):
- return True
-
-def countchanges(hunk):
- """hunk -> (n+,n-)"""
- add = len([h for h in hunk if h[0] == '+'])
- rem = len([h for h in hunk if h[0] == '-'])
- return add, rem
-
-class hunk(object):
- """patch hunk
-
- XXX shouldn't we merge this with patch.hunk ?
- """
- maxcontext = 3
-
- def __init__(self, header, fromline, toline, proc, before, hunk, after):
- def trimcontext(number, lines):
- delta = len(lines) - self.maxcontext
- if False and delta > 0:
- return number + delta, lines[:self.maxcontext]
- return number, lines
-
- self.header = header
- self.fromline, self.before = trimcontext(fromline, before)
- self.toline, self.after = trimcontext(toline, after)
- self.proc = proc
- self.hunk = hunk
- self.added, self.removed = countchanges(self.hunk)
-
- def write(self, fp):
- delta = len(self.before) + len(self.after)
- if self.after and self.after[-1] == '\\ No newline at end of file\n':
- delta -= 1
- fromlen = delta + self.removed
- tolen = delta + self.added
- fp.write('@@ -%d,%d +%d,%d @@%s\n' %
- (self.fromline, fromlen, self.toline, tolen,
- self.proc and (' ' + self.proc)))
- fp.write(''.join(self.before + self.hunk + self.after))
-
- pretty = write
-
- def filename(self):
- return self.header.filename()
-
- def __repr__(self):
- return '<hunk %r@%d>' % (self.filename(), self.fromline)
-
-def parsepatch(fp):
- """patch -> [] of hunks """
- class parser(object):
- """patch parsing state machine"""
- def __init__(self):
- self.fromline = 0
- self.toline = 0
- self.proc = ''
- self.header = None
- self.context = []
- self.before = []
- self.hunk = []
- self.stream = []
-
- def addrange(self, limits):
- fromstart, fromend, tostart, toend, proc = limits
- self.fromline = int(fromstart)
- self.toline = int(tostart)
- self.proc = proc
-
- def addcontext(self, context):
- if self.hunk:
- h = hunk(self.header, self.fromline, self.toline, self.proc,
- self.before, self.hunk, context)
- self.header.hunks.append(h)
- self.stream.append(h)
- self.fromline += len(self.before) + h.removed
- self.toline += len(self.before) + h.added
- self.before = []
- self.hunk = []
- self.proc = ''
- self.context = context
-
- def addhunk(self, hunk):
- if self.context:
- self.before = self.context
- self.context = []
- self.hunk = hunk
-
- def newfile(self, hdr):
- self.addcontext([])
- h = header(hdr)
- self.stream.append(h)
- self.header = h
-
- def finished(self):
- self.addcontext([])
- return self.stream
-
- transitions = {
- 'file': {'context': addcontext,
- 'file': newfile,
- 'hunk': addhunk,
- 'range': addrange},
- 'context': {'file': newfile,
- 'hunk': addhunk,
- 'range': addrange},
- 'hunk': {'context': addcontext,
- 'file': newfile,
- 'range': addrange},
- 'range': {'context': addcontext,
- 'hunk': addhunk},
- }
-
- p = parser()
-
- state = 'context'
- for newstate, data in scanpatch(fp):
- try:
- p.transitions[state][newstate](p, data)
- except KeyError:
- raise patch.PatchError('unhandled transition: %s -> %s' %
- (state, newstate))
- state = newstate
- return p.finished()
-
-def filterpatch(ui, chunks):
- """Interactively filter patch chunks into applied-only chunks"""
- chunks = list(chunks)
- chunks.reverse()
- seen = set()
- def consumefile():
- """fetch next portion from chunks until a 'header' is seen
- NB: header == new-file mark
- """
- consumed = []
- while chunks:
- if isinstance(chunks[-1], header):
- break
- else:
- consumed.append(chunks.pop())
- return consumed
-
- resp_all = [None] # this two are changed from inside prompt,
- resp_file = [None] # so can't be usual variables
- applied = {} # 'filename' -> [] of chunks
- def prompt(query):
- """prompt query, and process base inputs
-
- - y/n for the rest of file
- - y/n for the rest
- - ? (help)
- - q (quit)
-
- Returns True/False and sets reps_all and resp_file as
- appropriate.
- """
- if resp_all[0] is not None:
- return resp_all[0]
- if resp_file[0] is not None:
- return resp_file[0]
- while True:
- resps = _('[Ynsfdaq?]')
- choices = (_('&Yes, record this change'),
- _('&No, skip this change'),
- _('&Skip remaining changes to this file'),
- _('Record remaining changes to this &file'),
- _('&Done, skip remaining changes and files'),
- _('Record &all changes to all remaining files'),
- _('&Quit, recording no changes'),
- _('&?'))
- r = ui.promptchoice("%s %s" % (query, resps), choices)
- ui.write("\n")
- if r == 7: # ?
- doc = gettext(record.__doc__)
- c = doc.find('::') + 2
- for l in doc[c:].splitlines():
- if l.startswith(' '):
- ui.write(l.strip(), '\n')
- continue
- elif r == 0: # yes
- ret = True
- elif r == 1: # no
- ret = False
- elif r == 2: # Skip
- ret = resp_file[0] = False
- elif r == 3: # file (Record remaining)
- ret = resp_file[0] = True
- elif r == 4: # done, skip remaining
- ret = resp_all[0] = False
- elif r == 5: # all
- ret = resp_all[0] = True
- elif r == 6: # quit
- raise util.Abort(_('user quit'))
- return ret
- pos, total = 0, len(chunks) - 1
- while chunks:
- pos = total - len(chunks) + 1
- chunk = chunks.pop()
- if isinstance(chunk, header):
- # new-file mark
- resp_file = [None]
- fixoffset = 0
- hdr = ''.join(chunk.header)
- if hdr in seen:
- consumefile()
- continue
- seen.add(hdr)
- if resp_all[0] is None:
- chunk.pretty(ui)
- r = prompt(_('examine changes to %s?') %
- _(' and ').join(map(repr, chunk.files())))
- if r:
- applied[chunk.filename()] = [chunk]
- if chunk.allhunks():
- applied[chunk.filename()] += consumefile()
- else:
- consumefile()
- else:
- # new hunk
- if resp_file[0] is None and resp_all[0] is None:
- chunk.pretty(ui)
- r = total == 1 and prompt(_('record this change to %r?') %
- chunk.filename()) \
- or prompt(_('record change %d/%d to %r?') %
- (pos, total, chunk.filename()))
- if r:
- if fixoffset:
- chunk = copy.copy(chunk)
- chunk.toline += fixoffset
- applied[chunk.filename()].append(chunk)
- else:
- fixoffset += chunk.removed - chunk.added
- return sum([h for h in applied.itervalues()
- if h[0].special() or len(h) > 1], [])
-
-def record(ui, repo, *pats, **opts):
- '''interactively select changes to commit
-
- If a list of files is omitted, all changes reported by :hg:`status`
- will be candidates for recording.
-
- See :hg:`help dates` for a list of formats valid for -d/--date.
-
- You will be prompted for whether to record changes to each
- modified file, and for files with multiple changes, for each
- change to use. For each query, the following responses are
- possible::
-
- y - record this change
- n - skip this change
-
- s - skip remaining changes to this file
- f - record remaining changes to this file
-
- d - done, skip remaining changes and files
- a - record all changes to all remaining files
- q - quit, recording no changes
-
- ? - display help
-
- This command is not available when committing a merge.'''
-
- dorecord(ui, repo, commands.commit, *pats, **opts)
-
-
-def qrecord(ui, repo, patch, *pats, **opts):
- '''interactively record a new patch
-
- See :hg:`help qnew` & :hg:`help record` for more information and
- usage.
- '''
-
- try:
- mq = extensions.find('mq')
- except KeyError:
- raise util.Abort(_("'mq' extension not loaded"))
-
- def committomq(ui, repo, *pats, **opts):
- mq.new(ui, repo, patch, *pats, **opts)
-
- opts = opts.copy()
- opts['force'] = True # always 'qnew -f'
- dorecord(ui, repo, committomq, *pats, **opts)
-
-
-def dorecord(ui, repo, commitfunc, *pats, **opts):
- if not ui.interactive():
- raise util.Abort(_('running non-interactively, use commit instead'))
-
- def recordfunc(ui, repo, message, match, opts):
- """This is generic record driver.
-
- Its job is to interactively filter local changes, and accordingly
- prepare working dir into a state, where the job can be delegated to
- non-interactive commit command such as 'commit' or 'qrefresh'.
-
- After the actual job is done by non-interactive command, working dir
- state is restored to original.
-
- In the end we'll record interesting changes, and everything else will be
- left in place, so the user can continue his work.
- """
-
- merge = len(repo[None].parents()) > 1
- if merge:
- raise util.Abort(_('cannot partially commit a merge '
- '(use hg commit instead)'))
-
- changes = repo.status(match=match)[:3]
- diffopts = mdiff.diffopts(git=True, nodates=True)
- chunks = patch.diff(repo, changes=changes, opts=diffopts)
- fp = cStringIO.StringIO()
- fp.write(''.join(chunks))
- fp.seek(0)
-
- # 1. filter patch, so we have intending-to apply subset of it
- chunks = filterpatch(ui, parsepatch(fp))
- del fp
-
- contenders = set()
- for h in chunks:
- try:
- contenders.update(set(h.files()))
- except AttributeError:
- pass
-
- changed = changes[0] + changes[1] + changes[2]
- newfiles = [f for f in changed if f in contenders]
- if not newfiles:
- ui.status(_('no changes to record\n'))
- return 0
-
- modified = set(changes[0])
-
- # 2. backup changed files, so we can restore them in the end
- backups = {}
- backupdir = repo.join('record-backups')
- try:
- os.mkdir(backupdir)
- except OSError, err:
- if err.errno != errno.EEXIST:
- raise
- try:
- # backup continues
- for f in newfiles:
- if f not in modified:
- continue
- fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
- dir=backupdir)
- os.close(fd)
- ui.debug('backup %r as %r\n' % (f, tmpname))
- util.copyfile(repo.wjoin(f), tmpname)
- backups[f] = tmpname
-
- fp = cStringIO.StringIO()
- for c in chunks:
- if c.filename() in backups:
- c.write(fp)
- dopatch = fp.tell()
- fp.seek(0)
-
- # 3a. apply filtered patch to clean repo (clean)
- if backups:
- hg.revert(repo, repo.dirstate.parents()[0],
- lambda key: key in backups)
-
- # 3b. (apply)
- if dopatch:
- try:
- ui.debug('applying patch\n')
- ui.debug(fp.getvalue())
- pfiles = {}
- patch.internalpatch(fp, ui, 1, repo.root, files=pfiles,
- eolmode=None)
- cmdutil.updatedir(ui, repo, pfiles)
- except patch.PatchError, err:
- raise util.Abort(str(err))
- del fp
-
- # 4. We prepared working directory according to filtered patch.
- # Now is the time to delegate the job to commit/qrefresh or the like!
-
- # it is important to first chdir to repo root -- we'll call a
- # highlevel command with list of pathnames relative to repo root
- cwd = os.getcwd()
- os.chdir(repo.root)
- try:
- commitfunc(ui, repo, *newfiles, **opts)
- finally:
- os.chdir(cwd)
-
- return 0
- finally:
- # 5. finally restore backed-up files
- try:
- for realname, tmpname in backups.iteritems():
- ui.debug('restoring %r to %r\n' % (tmpname, realname))
- util.copyfile(tmpname, repo.wjoin(realname))
- os.unlink(tmpname)
- os.rmdir(backupdir)
- except OSError:
- pass
-
- # wrap ui.write so diff output can be labeled/colorized
- def wrapwrite(orig, *args, **kw):
- label = kw.pop('label', '')
- for chunk, l in patch.difflabel(lambda: args):
- orig(chunk, label=label + l)
- oldwrite = ui.write
- extensions.wrapfunction(ui, 'write', wrapwrite)
- try:
- return cmdutil.commit(ui, repo, recordfunc, pats, opts)
- finally:
- ui.write = oldwrite
-
-cmdtable = {
- "record":
- (record,
-
- # add commit options
- commands.table['^commit|ci'][1],
-
- _('hg record [OPTION]... [FILE]...')),
-}
-
-
-def uisetup(ui):
- try:
- mq = extensions.find('mq')
- except KeyError:
- return
-
- qcmdtable = {
- "qrecord":
- (qrecord,
-
- # add qnew options, except '--force'
- [opt for opt in mq.cmdtable['^qnew'][1] if opt[1] != 'force'],
-
- _('hg qrecord [OPTION]... PATCH [FILE]...')),
- }
-
- cmdtable.update(qcmdtable)
-
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.pyo
deleted file mode 100644
index 456b7d6..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/record.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.py
deleted file mode 100644
index 77bd3c3..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# Mercurial extension to provide 'hg relink' command
-#
-# Copyright (C) 2007 Brendan Cully <brendan@kublai.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-"""recreates hardlinks between repository clones"""
-
-from mercurial import hg, util
-from mercurial.i18n import _
-import os, stat
-
-def relink(ui, repo, origin=None, **opts):
- """recreate hardlinks between two repositories
-
- When repositories are cloned locally, their data files will be
- hardlinked so that they only use the space of a single repository.
-
- Unfortunately, subsequent pulls into either repository will break
- hardlinks for any files touched by the new changesets, even if
- both repositories end up pulling the same changes.
-
- Similarly, passing --rev to "hg clone" will fail to use any
- hardlinks, falling back to a complete copy of the source
- repository.
-
- This command lets you recreate those hardlinks and reclaim that
- wasted space.
-
- This repository will be relinked to share space with ORIGIN, which
- must be on the same local disk. If ORIGIN is omitted, looks for
- "default-relink", then "default", in [paths].
-
- Do not attempt any read operations on this repository while the
- command is running. (Both repositories will be locked against
- writes.)
- """
- if not hasattr(util, 'samefile') or not hasattr(util, 'samedevice'):
- raise util.Abort(_('hardlinks are not supported on this system'))
- src = hg.repository(
- hg.remoteui(repo, opts),
- ui.expandpath(origin or 'default-relink', origin or 'default'))
- if not src.local():
- raise util.Abort('must specify local origin repository')
- ui.status(_('relinking %s to %s\n') % (src.store.path, repo.store.path))
- locallock = repo.lock()
- try:
- remotelock = src.lock()
- try:
- candidates = sorted(collect(src, ui))
- targets = prune(candidates, src.store.path, repo.store.path, ui)
- do_relink(src.store.path, repo.store.path, targets, ui)
- finally:
- remotelock.release()
- finally:
- locallock.release()
-
-def collect(src, ui):
- seplen = len(os.path.sep)
- candidates = []
- live = len(src['tip'].manifest())
- # Your average repository has some files which were deleted before
- # the tip revision. We account for that by assuming that there are
- # 3 tracked files for every 2 live files as of the tip version of
- # the repository.
- #
- # mozilla-central as of 2010-06-10 had a ratio of just over 7:5.
- total = live * 3 // 2
- src = src.store.path
- pos = 0
- ui.status(_("tip has %d files, estimated total number of files: %s\n")
- % (live, total))
- for dirpath, dirnames, filenames in os.walk(src):
- dirnames.sort()
- relpath = dirpath[len(src) + seplen:]
- for filename in sorted(filenames):
- if not filename[-2:] in ('.d', '.i'):
- continue
- st = os.stat(os.path.join(dirpath, filename))
- if not stat.S_ISREG(st.st_mode):
- continue
- pos += 1
- candidates.append((os.path.join(relpath, filename), st))
- ui.progress(_('collecting'), pos, filename, _('files'), total)
-
- ui.progress(_('collecting'), None)
- ui.status(_('collected %d candidate storage files\n') % len(candidates))
- return candidates
-
-def prune(candidates, src, dst, ui):
- def linkfilter(src, dst, st):
- try:
- ts = os.stat(dst)
- except OSError:
- # Destination doesn't have this file?
- return False
- if util.samefile(src, dst):
- return False
- if not util.samedevice(src, dst):
- # No point in continuing
- raise util.Abort(
- _('source and destination are on different devices'))
- if st.st_size != ts.st_size:
- return False
- return st
-
- targets = []
- total = len(candidates)
- pos = 0
- for fn, st in candidates:
- pos += 1
- srcpath = os.path.join(src, fn)
- tgt = os.path.join(dst, fn)
- ts = linkfilter(srcpath, tgt, st)
- if not ts:
- ui.debug(_('not linkable: %s\n') % fn)
- continue
- targets.append((fn, ts.st_size))
- ui.progress(_('pruning'), pos, fn, _('files'), total)
-
- ui.progress(_('pruning'), None)
- ui.status(_('pruned down to %d probably relinkable files\n') % len(targets))
- return targets
-
-def do_relink(src, dst, files, ui):
- def relinkfile(src, dst):
- bak = dst + '.bak'
- os.rename(dst, bak)
- try:
- util.os_link(src, dst)
- except OSError:
- os.rename(bak, dst)
- raise
- os.remove(bak)
-
- CHUNKLEN = 65536
- relinked = 0
- savedbytes = 0
-
- pos = 0
- total = len(files)
- for f, sz in files:
- pos += 1
- source = os.path.join(src, f)
- tgt = os.path.join(dst, f)
- # Binary mode, so that read() works correctly, especially on Windows
- sfp = file(source, 'rb')
- dfp = file(tgt, 'rb')
- sin = sfp.read(CHUNKLEN)
- while sin:
- din = dfp.read(CHUNKLEN)
- if sin != din:
- break
- sin = sfp.read(CHUNKLEN)
- sfp.close()
- dfp.close()
- if sin:
- ui.debug(_('not linkable: %s\n') % f)
- continue
- try:
- relinkfile(source, tgt)
- ui.progress(_('relinking'), pos, f, _('files'), total)
- relinked += 1
- savedbytes += sz
- except OSError, inst:
- ui.warn('%s: %s\n' % (tgt, str(inst)))
-
- ui.progress(_('relinking'), None)
-
- ui.status(_('relinked %d files (%d bytes reclaimed)\n') %
- (relinked, savedbytes))
-
-cmdtable = {
- 'relink': (
- relink,
- [],
- _('[ORIGIN]')
- )
-}
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.pyo
deleted file mode 100644
index 61565b1..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/relink.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.py
deleted file mode 100644
index ac9a8be..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-"""extend schemes with shortcuts to repository swarms
-
-This extension allows you to specify shortcuts for parent URLs with a
-lot of repositories to act like a scheme, for example::
-
- [schemes]
- py = http://code.python.org/hg/
-
-After that you can use it like::
-
- hg clone py://trunk/
-
-Additionally there is support for some more complex schemas, for
-example used by Google Code::
-
- [schemes]
- gcode = http://{1}.googlecode.com/hg/
-
-The syntax is taken from Mercurial templates, and you have unlimited
-number of variables, starting with ``{1}`` and continuing with
-``{2}``, ``{3}`` and so on. This variables will receive parts of URL
-supplied, split by ``/``. Anything not specified as ``{part}`` will be
-just appended to an URL.
-
-For convenience, the extension adds these schemes by default::
-
- [schemes]
- py = http://hg.python.org/
- bb = https://bitbucket.org/
- bb+ssh = ssh://hg@bitbucket.org/
- gcode = https://{1}.googlecode.com/hg/
- kiln = https://{1}.kilnhg.com/Repo/
-
-You can override a predefined scheme by defining a new scheme with the
-same name.
-"""
-
-import re
-from mercurial import hg, templater
-
-
-class ShortRepository(object):
- def __init__(self, url, scheme, templater):
- self.scheme = scheme
- self.templater = templater
- self.url = url
- try:
- self.parts = max(map(int, re.findall(r'\{(\d+)\}', self.url)))
- except ValueError:
- self.parts = 0
-
- def __repr__(self):
- return '<ShortRepository: %s>' % self.scheme
-
- def instance(self, ui, url, create):
- url = url.split('://', 1)[1]
- parts = url.split('/', self.parts)
- if len(parts) > self.parts:
- tail = parts[-1]
- parts = parts[:-1]
- else:
- tail = ''
- context = dict((str(i + 1), v) for i, v in enumerate(parts))
- url = ''.join(self.templater.process(self.url, context)) + tail
- return hg._lookup(url).instance(ui, url, create)
-
-schemes = {
- 'py': 'http://hg.python.org/',
- 'bb': 'https://bitbucket.org/',
- 'bb+ssh': 'ssh://hg@bitbucket.org/',
- 'gcode': 'https://{1}.googlecode.com/hg/',
- 'kiln': 'https://{1}.kilnhg.com/Repo/'
- }
-
-def extsetup(ui):
- schemes.update(dict(ui.configitems('schemes')))
- t = templater.engine(lambda x: x)
- for scheme, url in schemes.items():
- hg.schemes[scheme] = ShortRepository(url, scheme, t)
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.pyo
deleted file mode 100644
index a089ec3..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/schemes.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.py
deleted file mode 100644
index cc33148..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2006, 2007 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.
-
-'''share a common history between several working directories'''
-
-from mercurial.i18n import _
-from mercurial import hg, commands
-
-def share(ui, source, dest=None, noupdate=False):
- """create a new shared repository
-
- Initialize a new repository and working directory that shares its
- history with another repository.
-
- .. note::
- using rollback or extensions that destroy/modify history (mq,
- rebase, etc.) can cause considerable confusion with shared
- clones. In particular, if two shared clones are both updated to
- the same changeset, and one of them destroys that changeset
- with rollback, the other clone will suddenly stop working: all
- operations will fail with "abort: working directory has unknown
- parent". The only known workaround is to use debugsetparents on
- the broken clone to reset it to a changeset that still exists
- (e.g. tip).
- """
-
- return hg.share(ui, source, dest, not noupdate)
-
-cmdtable = {
- "share":
- (share,
- [('U', 'noupdate', None, _('do not create a working copy'))],
- _('[-U] SOURCE [DEST]')),
-}
-
-commands.norepo += " share"
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.pyo
deleted file mode 100644
index f4fca90..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/share.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.py
deleted file mode 100644
index 4325d9b..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.py
+++ /dev/null
@@ -1,630 +0,0 @@
-# Patch transplanting extension for Mercurial
-#
-# Copyright 2006, 2007 Brendan Cully <brendan@kublai.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''command to transplant changesets from another branch
-
-This extension allows you to transplant patches from another branch.
-
-Transplanted patches are recorded in .hg/transplant/transplants, as a
-map from a changeset hash to its hash in the source repository.
-'''
-
-from mercurial.i18n import _
-import os, tempfile
-from mercurial import bundlerepo, cmdutil, hg, merge, match
-from mercurial import patch, revlog, util, error
-from mercurial import revset
-
-class transplantentry(object):
- def __init__(self, lnode, rnode):
- self.lnode = lnode
- self.rnode = rnode
-
-class transplants(object):
- def __init__(self, path=None, transplantfile=None, opener=None):
- self.path = path
- self.transplantfile = transplantfile
- self.opener = opener
-
- if not opener:
- self.opener = util.opener(self.path)
- self.transplants = {}
- self.dirty = False
- self.read()
-
- def read(self):
- abspath = os.path.join(self.path, self.transplantfile)
- if self.transplantfile and os.path.exists(abspath):
- for line in self.opener(self.transplantfile).read().splitlines():
- lnode, rnode = map(revlog.bin, line.split(':'))
- list = self.transplants.setdefault(rnode, [])
- list.append(transplantentry(lnode, rnode))
-
- def write(self):
- if self.dirty and self.transplantfile:
- if not os.path.isdir(self.path):
- os.mkdir(self.path)
- fp = self.opener(self.transplantfile, 'w')
- for list in self.transplants.itervalues():
- for t in list:
- l, r = map(revlog.hex, (t.lnode, t.rnode))
- fp.write(l + ':' + r + '\n')
- fp.close()
- self.dirty = False
-
- def get(self, rnode):
- return self.transplants.get(rnode) or []
-
- def set(self, lnode, rnode):
- list = self.transplants.setdefault(rnode, [])
- list.append(transplantentry(lnode, rnode))
- self.dirty = True
-
- def remove(self, transplant):
- list = self.transplants.get(transplant.rnode)
- if list:
- del list[list.index(transplant)]
- self.dirty = True
-
-class transplanter(object):
- def __init__(self, ui, repo):
- self.ui = ui
- self.path = repo.join('transplant')
- self.opener = util.opener(self.path)
- self.transplants = transplants(self.path, 'transplants',
- opener=self.opener)
-
- def applied(self, repo, node, parent):
- '''returns True if a node is already an ancestor of parent
- or has already been transplanted'''
- if hasnode(repo, node):
- if node in repo.changelog.reachable(parent, stop=node):
- return True
- for t in self.transplants.get(node):
- # it might have been stripped
- if not hasnode(repo, t.lnode):
- self.transplants.remove(t)
- return False
- if t.lnode in repo.changelog.reachable(parent, stop=t.lnode):
- return True
- return False
-
- def apply(self, repo, source, revmap, merges, opts={}):
- '''apply the revisions in revmap one by one in revision order'''
- revs = sorted(revmap)
- p1, p2 = repo.dirstate.parents()
- pulls = []
- diffopts = patch.diffopts(self.ui, opts)
- diffopts.git = True
-
- lock = wlock = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- for rev in revs:
- node = revmap[rev]
- revstr = '%s:%s' % (rev, revlog.short(node))
-
- if self.applied(repo, node, p1):
- self.ui.warn(_('skipping already applied revision %s\n') %
- revstr)
- continue
-
- parents = source.changelog.parents(node)
- if not opts.get('filter'):
- # If the changeset parent is the same as the
- # wdir's parent, just pull it.
- if parents[0] == p1:
- pulls.append(node)
- p1 = node
- continue
- if pulls:
- if source != repo:
- repo.pull(source, heads=pulls)
- merge.update(repo, pulls[-1], False, False, None)
- p1, p2 = repo.dirstate.parents()
- pulls = []
-
- domerge = False
- if node in merges:
- # pulling all the merge revs at once would mean we
- # couldn't transplant after the latest even if
- # transplants before them fail.
- domerge = True
- if not hasnode(repo, node):
- repo.pull(source, heads=[node])
-
- if parents[1] != revlog.nullid:
- self.ui.note(_('skipping merge changeset %s:%s\n')
- % (rev, revlog.short(node)))
- patchfile = None
- else:
- fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
- fp = os.fdopen(fd, 'w')
- gen = patch.diff(source, parents[0], node, opts=diffopts)
- for chunk in gen:
- fp.write(chunk)
- fp.close()
-
- del revmap[rev]
- if patchfile or domerge:
- try:
- n = self.applyone(repo, node,
- source.changelog.read(node),
- patchfile, merge=domerge,
- log=opts.get('log'),
- filter=opts.get('filter'))
- if n and domerge:
- self.ui.status(_('%s merged at %s\n') % (revstr,
- revlog.short(n)))
- elif n:
- self.ui.status(_('%s transplanted to %s\n')
- % (revlog.short(node),
- revlog.short(n)))
- finally:
- if patchfile:
- os.unlink(patchfile)
- if pulls:
- repo.pull(source, heads=pulls)
- merge.update(repo, pulls[-1], False, False, None)
- finally:
- self.saveseries(revmap, merges)
- self.transplants.write()
- lock.release()
- wlock.release()
-
- def filter(self, filter, changelog, patchfile):
- '''arbitrarily rewrite changeset before applying it'''
-
- self.ui.status(_('filtering %s\n') % patchfile)
- user, date, msg = (changelog[1], changelog[2], changelog[4])
-
- fd, headerfile = tempfile.mkstemp(prefix='hg-transplant-')
- fp = os.fdopen(fd, 'w')
- fp.write("# HG changeset patch\n")
- fp.write("# User %s\n" % user)
- fp.write("# Date %d %d\n" % date)
- fp.write(msg + '\n')
- fp.close()
-
- try:
- util.system('%s %s %s' % (filter, util.shellquote(headerfile),
- util.shellquote(patchfile)),
- environ={'HGUSER': changelog[1]},
- onerr=util.Abort, errprefix=_('filter failed'))
- user, date, msg = self.parselog(file(headerfile))[1:4]
- finally:
- os.unlink(headerfile)
-
- return (user, date, msg)
-
- def applyone(self, repo, node, cl, patchfile, merge=False, log=False,
- filter=None):
- '''apply the patch in patchfile to the repository as a transplant'''
- (manifest, user, (time, timezone), files, message) = cl[:5]
- date = "%d %d" % (time, timezone)
- extra = {'transplant_source': node}
- if filter:
- (user, date, message) = self.filter(filter, cl, patchfile)
-
- if log:
- # we don't translate messages inserted into commits
- message += '\n(transplanted from %s)' % revlog.hex(node)
-
- self.ui.status(_('applying %s\n') % revlog.short(node))
- self.ui.note('%s %s\n%s\n' % (user, date, message))
-
- if not patchfile and not merge:
- raise util.Abort(_('can only omit patchfile if merging'))
- if patchfile:
- try:
- files = {}
- try:
- patch.patch(patchfile, self.ui, cwd=repo.root,
- files=files, eolmode=None)
- if not files:
- self.ui.warn(_('%s: empty changeset')
- % revlog.hex(node))
- return None
- finally:
- files = cmdutil.updatedir(self.ui, repo, files)
- except Exception, inst:
- seriespath = os.path.join(self.path, 'series')
- if os.path.exists(seriespath):
- os.unlink(seriespath)
- p1 = repo.dirstate.parents()[0]
- p2 = node
- self.log(user, date, message, p1, p2, merge=merge)
- self.ui.write(str(inst) + '\n')
- raise util.Abort(_('fix up the merge and run '
- 'hg transplant --continue'))
- else:
- files = None
- if merge:
- p1, p2 = repo.dirstate.parents()
- repo.dirstate.setparents(p1, node)
- m = match.always(repo.root, '')
- else:
- m = match.exact(repo.root, '', files)
-
- n = repo.commit(message, user, date, extra=extra, match=m)
- if not n:
- # Crash here to prevent an unclear crash later, in
- # transplants.write(). This can happen if patch.patch()
- # does nothing but claims success or if repo.status() fails
- # to report changes done by patch.patch(). These both
- # appear to be bugs in other parts of Mercurial, but dying
- # here, as soon as we can detect the problem, is preferable
- # to silently dropping changesets on the floor.
- raise RuntimeError('nothing committed after transplant')
- if not merge:
- self.transplants.set(n, node)
-
- return n
-
- def resume(self, repo, source, opts=None):
- '''recover last transaction and apply remaining changesets'''
- if os.path.exists(os.path.join(self.path, 'journal')):
- n, node = self.recover(repo)
- self.ui.status(_('%s transplanted as %s\n') % (revlog.short(node),
- revlog.short(n)))
- seriespath = os.path.join(self.path, 'series')
- if not os.path.exists(seriespath):
- self.transplants.write()
- return
- nodes, merges = self.readseries()
- revmap = {}
- for n in nodes:
- revmap[source.changelog.rev(n)] = n
- os.unlink(seriespath)
-
- self.apply(repo, source, revmap, merges, opts)
-
- def recover(self, repo):
- '''commit working directory using journal metadata'''
- node, user, date, message, parents = self.readlog()
- merge = len(parents) == 2
-
- if not user or not date or not message or not parents[0]:
- raise util.Abort(_('transplant log file is corrupt'))
-
- extra = {'transplant_source': node}
- wlock = repo.wlock()
- try:
- p1, p2 = repo.dirstate.parents()
- if p1 != parents[0]:
- raise util.Abort(
- _('working dir not at transplant parent %s') %
- revlog.hex(parents[0]))
- if merge:
- repo.dirstate.setparents(p1, parents[1])
- n = repo.commit(message, user, date, extra=extra)
- if not n:
- raise util.Abort(_('commit failed'))
- if not merge:
- self.transplants.set(n, node)
- self.unlog()
-
- return n, node
- finally:
- wlock.release()
-
- def readseries(self):
- nodes = []
- merges = []
- cur = nodes
- for line in self.opener('series').read().splitlines():
- if line.startswith('# Merges'):
- cur = merges
- continue
- cur.append(revlog.bin(line))
-
- return (nodes, merges)
-
- def saveseries(self, revmap, merges):
- if not revmap:
- return
-
- if not os.path.isdir(self.path):
- os.mkdir(self.path)
- series = self.opener('series', 'w')
- for rev in sorted(revmap):
- series.write(revlog.hex(revmap[rev]) + '\n')
- if merges:
- series.write('# Merges\n')
- for m in merges:
- series.write(revlog.hex(m) + '\n')
- series.close()
-
- def parselog(self, fp):
- parents = []
- message = []
- node = revlog.nullid
- inmsg = False
- for line in fp.read().splitlines():
- if inmsg:
- message.append(line)
- elif line.startswith('# User '):
- user = line[7:]
- elif line.startswith('# Date '):
- date = line[7:]
- elif line.startswith('# Node ID '):
- node = revlog.bin(line[10:])
- elif line.startswith('# Parent '):
- parents.append(revlog.bin(line[9:]))
- elif not line.startswith('# '):
- inmsg = True
- message.append(line)
- return (node, user, date, '\n'.join(message), parents)
-
- def log(self, user, date, message, p1, p2, merge=False):
- '''journal changelog metadata for later recover'''
-
- if not os.path.isdir(self.path):
- os.mkdir(self.path)
- fp = self.opener('journal', 'w')
- fp.write('# User %s\n' % user)
- fp.write('# Date %s\n' % date)
- fp.write('# Node ID %s\n' % revlog.hex(p2))
- fp.write('# Parent ' + revlog.hex(p1) + '\n')
- if merge:
- fp.write('# Parent ' + revlog.hex(p2) + '\n')
- fp.write(message.rstrip() + '\n')
- fp.close()
-
- def readlog(self):
- return self.parselog(self.opener('journal'))
-
- def unlog(self):
- '''remove changelog journal'''
- absdst = os.path.join(self.path, 'journal')
- if os.path.exists(absdst):
- os.unlink(absdst)
-
- def transplantfilter(self, repo, source, root):
- def matchfn(node):
- if self.applied(repo, node, root):
- return False
- if source.changelog.parents(node)[1] != revlog.nullid:
- return False
- extra = source.changelog.read(node)[5]
- cnode = extra.get('transplant_source')
- if cnode and self.applied(repo, cnode, root):
- return False
- return True
-
- return matchfn
-
-def hasnode(repo, node):
- try:
- return repo.changelog.rev(node) != None
- except error.RevlogError:
- return False
-
-def browserevs(ui, repo, nodes, opts):
- '''interactively transplant changesets'''
- def browsehelp(ui):
- ui.write(_('y: transplant this changeset\n'
- 'n: skip this changeset\n'
- 'm: merge at this changeset\n'
- 'p: show patch\n'
- 'c: commit selected changesets\n'
- 'q: cancel transplant\n'
- '?: show this help\n'))
-
- displayer = cmdutil.show_changeset(ui, repo, opts)
- transplants = []
- merges = []
- for node in nodes:
- displayer.show(repo[node])
- action = None
- while not action:
- action = ui.prompt(_('apply changeset? [ynmpcq?]:'))
- if action == '?':
- browsehelp(ui)
- action = None
- elif action == 'p':
- parent = repo.changelog.parents(node)[0]
- for chunk in patch.diff(repo, parent, node):
- ui.write(chunk)
- action = None
- elif action not in ('y', 'n', 'm', 'c', 'q'):
- ui.write(_('no such option\n'))
- action = None
- if action == 'y':
- transplants.append(node)
- elif action == 'm':
- merges.append(node)
- elif action == 'c':
- break
- elif action == 'q':
- transplants = ()
- merges = ()
- break
- displayer.close()
- return (transplants, merges)
-
-def transplant(ui, repo, *revs, **opts):
- '''transplant changesets from another branch
-
- Selected changesets will be applied on top of the current working
- directory with the log of the original changeset. If --log is
- specified, log messages will have a comment appended of the form::
-
- (transplanted from CHANGESETHASH)
-
- You can rewrite the changelog message with the --filter option.
- Its argument will be invoked with the current changelog message as
- $1 and the patch as $2.
-
- If --source/-s is specified, selects changesets from the named
- repository. If --branch/-b is specified, selects changesets from
- the branch holding the named revision, up to that revision. If
- --all/-a is specified, all changesets on the branch will be
- transplanted, otherwise you will be prompted to select the
- changesets you want.
-
- :hg:`transplant --branch REVISION --all` will rebase the selected
- branch (up to the named revision) onto your current working
- directory.
-
- You can optionally mark selected transplanted changesets as merge
- changesets. You will not be prompted to transplant any ancestors
- of a merged transplant, and you can merge descendants of them
- normally instead of transplanting them.
-
- If no merges or revisions are provided, :hg:`transplant` will
- start an interactive changeset browser.
-
- If a changeset application fails, you can fix the merge by hand
- and then resume where you left off by calling :hg:`transplant
- --continue/-c`.
- '''
- def incwalk(repo, incoming, branches, match=util.always):
- if not branches:
- branches = None
- for node in repo.changelog.nodesbetween(incoming, branches)[0]:
- if match(node):
- yield node
-
- def transplantwalk(repo, root, branches, match=util.always):
- if not branches:
- branches = repo.heads()
- ancestors = []
- for branch in branches:
- ancestors.append(repo.changelog.ancestor(root, branch))
- for node in repo.changelog.nodesbetween(ancestors, branches)[0]:
- if match(node):
- yield node
-
- def checkopts(opts, revs):
- if opts.get('continue'):
- if opts.get('branch') or opts.get('all') or opts.get('merge'):
- raise util.Abort(_('--continue is incompatible with '
- 'branch, all or merge'))
- return
- if not (opts.get('source') or revs or
- opts.get('merge') or opts.get('branch')):
- raise util.Abort(_('no source URL, branch tag or revision '
- 'list provided'))
- if opts.get('all'):
- if not opts.get('branch'):
- raise util.Abort(_('--all requires a branch revision'))
- if revs:
- raise util.Abort(_('--all is incompatible with a '
- 'revision list'))
-
- checkopts(opts, revs)
-
- if not opts.get('log'):
- opts['log'] = ui.config('transplant', 'log')
- if not opts.get('filter'):
- opts['filter'] = ui.config('transplant', 'filter')
-
- tp = transplanter(ui, repo)
-
- p1, p2 = repo.dirstate.parents()
- if len(repo) > 0 and p1 == revlog.nullid:
- raise util.Abort(_('no revision checked out'))
- if not opts.get('continue'):
- if p2 != revlog.nullid:
- raise util.Abort(_('outstanding uncommitted merges'))
- m, a, r, d = repo.status()[:4]
- if m or a or r or d:
- raise util.Abort(_('outstanding local changes'))
-
- bundle = None
- source = opts.get('source')
- if source:
- sourcerepo = ui.expandpath(source)
- source = hg.repository(ui, sourcerepo)
- source, incoming, bundle = bundlerepo.getremotechanges(ui, repo, source,
- force=True)
- else:
- source = repo
-
- try:
- if opts.get('continue'):
- tp.resume(repo, source, opts)
- return
-
- tf = tp.transplantfilter(repo, source, p1)
- if opts.get('prune'):
- prune = [source.lookup(r)
- for r in cmdutil.revrange(source, opts.get('prune'))]
- matchfn = lambda x: tf(x) and x not in prune
- else:
- matchfn = tf
- branches = map(source.lookup, opts.get('branch', ()))
- merges = map(source.lookup, opts.get('merge', ()))
- revmap = {}
- if revs:
- for r in cmdutil.revrange(source, revs):
- revmap[int(r)] = source.lookup(r)
- elif opts.get('all') or not merges:
- if source != repo:
- alltransplants = incwalk(source, incoming, branches,
- match=matchfn)
- else:
- alltransplants = transplantwalk(source, p1, branches,
- match=matchfn)
- if opts.get('all'):
- revs = alltransplants
- else:
- revs, newmerges = browserevs(ui, source, alltransplants, opts)
- merges.extend(newmerges)
- for r in revs:
- revmap[source.changelog.rev(r)] = r
- for r in merges:
- revmap[source.changelog.rev(r)] = r
-
- tp.apply(repo, source, revmap, merges, opts)
- finally:
- if bundle:
- source.close()
- os.unlink(bundle)
-
-def revsettransplanted(repo, subset, x):
- """``transplanted(set)``
- Transplanted changesets in set.
- """
- if x:
- s = revset.getset(repo, subset, x)
- else:
- s = subset
- cs = set()
- for r in xrange(0, len(repo)):
- if repo[r].extra().get('transplant_source'):
- cs.add(r)
- return [r for r in s if r in cs]
-
-def extsetup(ui):
- revset.symbols['transplanted'] = revsettransplanted
-
-cmdtable = {
- "transplant":
- (transplant,
- [('s', 'source', '',
- _('pull patches from REPO'), _('REPO')),
- ('b', 'branch', [],
- _('pull patches from branch BRANCH'), _('BRANCH')),
- ('a', 'all', None, _('pull all changesets up to BRANCH')),
- ('p', 'prune', [],
- _('skip over REV'), _('REV')),
- ('m', 'merge', [],
- _('merge at REV'), _('REV')),
- ('', 'log', None, _('append transplant info to log message')),
- ('c', 'continue', None, _('continue last transplant session '
- 'after repair')),
- ('', 'filter', '',
- _('filter changesets through command'), _('CMD'))],
- _('hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] '
- '[-m REV] [REV]...'))
-}
-
-# tell hggettext to extract docstrings from these functions:
-i18nfunctions = [revsettransplanted]
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.pyo
deleted file mode 100644
index a41b8f0..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/transplant.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.py
deleted file mode 100644
index f83c43e..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# win32mbcs.py -- MBCS filename support for Mercurial
-#
-# Copyright (c) 2008 Shun-ichi Goto <shunichi.goto@gmail.com>
-#
-# Version: 0.3
-# Author: Shun-ichi Goto <shunichi.goto@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-#
-
-'''allow the use of MBCS paths with problematic encodings
-
-Some MBCS encodings are not good for some path operations (i.e.
-splitting path, case conversion, etc.) with its encoded bytes. We call
-such a encoding (i.e. shift_jis and big5) as "problematic encoding".
-This extension can be used to fix the issue with those encodings by
-wrapping some functions to convert to Unicode string before path
-operation.
-
-This extension is useful for:
-
-- Japanese Windows users using shift_jis encoding.
-- Chinese Windows users using big5 encoding.
-- All users who use a repository with one of problematic encodings on
- case-insensitive file system.
-
-This extension is not needed for:
-
-- Any user who use only ASCII chars in path.
-- Any user who do not use any of problematic encodings.
-
-Note that there are some limitations on using this extension:
-
-- You should use single encoding in one repository.
-- If the repository path ends with 0x5c, .hg/hgrc cannot be read.
-- win32mbcs is not compatible with fixutf8 extention.
-
-By default, win32mbcs uses encoding.encoding decided by Mercurial.
-You can specify the encoding by config option::
-
- [win32mbcs]
- encoding = sjis
-
-It is useful for the users who want to commit with UTF-8 log message.
-'''
-
-import os, sys
-from mercurial.i18n import _
-from mercurial import util, encoding
-
-_encoding = None # see extsetup
-
-def decode(arg):
- if isinstance(arg, str):
- uarg = arg.decode(_encoding)
- if arg == uarg.encode(_encoding):
- return uarg
- raise UnicodeError("Not local encoding")
- elif isinstance(arg, tuple):
- return tuple(map(decode, arg))
- elif isinstance(arg, list):
- return map(decode, arg)
- elif isinstance(arg, dict):
- for k, v in arg.items():
- arg[k] = decode(v)
- return arg
-
-def encode(arg):
- if isinstance(arg, unicode):
- return arg.encode(_encoding)
- elif isinstance(arg, tuple):
- return tuple(map(encode, arg))
- elif isinstance(arg, list):
- return map(encode, arg)
- elif isinstance(arg, dict):
- for k, v in arg.items():
- arg[k] = encode(v)
- return arg
-
-def appendsep(s):
- # ensure the path ends with os.sep, appending it if necessary.
- try:
- us = decode(s)
- except UnicodeError:
- us = s
- if us and us[-1] not in ':/\\':
- s += os.sep
- return s
-
-def wrapper(func, args, kwds):
- # check argument is unicode, then call original
- for arg in args:
- if isinstance(arg, unicode):
- return func(*args, **kwds)
-
- try:
- # convert arguments to unicode, call func, then convert back
- return encode(func(*decode(args), **decode(kwds)))
- except UnicodeError:
- raise util.Abort(_("[win32mbcs] filename conversion failed with"
- " %s encoding\n") % (_encoding))
-
-def wrapperforlistdir(func, args, kwds):
- # Ensure 'path' argument ends with os.sep to avoids
- # misinterpreting last 0x5c of MBCS 2nd byte as path separator.
- if args:
- args = list(args)
- args[0] = appendsep(args[0])
- if 'path' in kwds:
- kwds['path'] = appendsep(kwds['path'])
- return func(*args, **kwds)
-
-def wrapname(name, wrapper):
- module, name = name.rsplit('.', 1)
- module = sys.modules[module]
- func = getattr(module, name)
- def f(*args, **kwds):
- return wrapper(func, args, kwds)
- try:
- f.__name__ = func.__name__ # fail with python23
- except Exception:
- pass
- setattr(module, name, f)
-
-# List of functions to be wrapped.
-# NOTE: os.path.dirname() and os.path.basename() are safe because
-# they use result of os.path.split()
-funcs = '''os.path.join os.path.split os.path.splitext
- os.path.splitunc os.path.normpath os.path.normcase os.makedirs
- mercurial.util.endswithsep mercurial.util.splitpath mercurial.util.checkcase
- mercurial.util.fspath mercurial.util.pconvert mercurial.util.normpath'''
-
-# codec and alias names of sjis and big5 to be faked.
-problematic_encodings = '''big5 big5-tw csbig5 big5hkscs big5-hkscs
- hkscs cp932 932 ms932 mskanji ms-kanji shift_jis csshiftjis shiftjis
- sjis s_jis shift_jis_2004 shiftjis2004 sjis_2004 sjis2004
- shift_jisx0213 shiftjisx0213 sjisx0213 s_jisx0213 950 cp950 ms950 '''
-
-def extsetup(ui):
- # TODO: decide use of config section for this extension
- if not os.path.supports_unicode_filenames:
- ui.warn(_("[win32mbcs] cannot activate on this platform.\n"))
- return
- # determine encoding for filename
- global _encoding
- _encoding = ui.config('win32mbcs', 'encoding', encoding.encoding)
- # fake is only for relevant environment.
- if _encoding.lower() in problematic_encodings.split():
- for f in funcs.split():
- wrapname(f, wrapper)
- wrapname("mercurial.osutil.listdir", wrapperforlistdir)
- # Check sys.args manually instead of using ui.debug() because
- # command line options is not yet applied when
- # extensions.loadall() is called.
- if '--debug' in sys.argv:
- ui.write("[win32mbcs] activated with encoding: %s\n"
- % _encoding)
-
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.pyo
deleted file mode 100644
index 43fac41..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32mbcs.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.py
deleted file mode 100644
index 82e6aed..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# win32text.py - LF <-> CRLF/CR translation utilities for Windows/Mac users
-#
-# Copyright 2005, 2007-2009 Matt Mackall <mpm@selenic.com> and others
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''perform automatic newline conversion
-
- Deprecation: The win32text extension requires each user to configure
- the extension again and again for each clone since the configuration
- is not copied when cloning.
-
- We have therefore made the ``eol`` as an alternative. The ``eol``
- uses a version controlled file for its configuration and each clone
- will therefore use the right settings from the start.
-
-To perform automatic newline conversion, use::
-
- [extensions]
- win32text =
- [encode]
- ** = cleverencode:
- # or ** = macencode:
-
- [decode]
- ** = cleverdecode:
- # or ** = macdecode:
-
-If not doing conversion, to make sure you do not commit CRLF/CR by accident::
-
- [hooks]
- pretxncommit.crlf = python:hgext.win32text.forbidcrlf
- # or pretxncommit.cr = python:hgext.win32text.forbidcr
-
-To do the same check on a server to prevent CRLF/CR from being
-pushed or pulled::
-
- [hooks]
- pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
- # or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
-'''
-
-from mercurial.i18n import _
-from mercurial.node import short
-from mercurial import util
-import re
-
-# regexp for single LF without CR preceding.
-re_single_lf = re.compile('(^|[^\r])\n', re.MULTILINE)
-
-newlinestr = {'\r\n': 'CRLF', '\r': 'CR'}
-filterstr = {'\r\n': 'clever', '\r': 'mac'}
-
-def checknewline(s, newline, ui=None, repo=None, filename=None):
- # warn if already has 'newline' in repository.
- # it might cause unexpected eol conversion.
- # see issue 302:
- # http://mercurial.selenic.com/bts/issue302
- if newline in s and ui and filename and repo:
- ui.warn(_('WARNING: %s already has %s line endings\n'
- 'and does not need EOL conversion by the win32text plugin.\n'
- 'Before your next commit, please reconsider your '
- 'encode/decode settings in \nMercurial.ini or %s.\n') %
- (filename, newlinestr[newline], repo.join('hgrc')))
-
-def dumbdecode(s, cmd, **kwargs):
- checknewline(s, '\r\n', **kwargs)
- # replace single LF to CRLF
- return re_single_lf.sub('\\1\r\n', s)
-
-def dumbencode(s, cmd):
- return s.replace('\r\n', '\n')
-
-def macdumbdecode(s, cmd, **kwargs):
- checknewline(s, '\r', **kwargs)
- return s.replace('\n', '\r')
-
-def macdumbencode(s, cmd):
- return s.replace('\r', '\n')
-
-def cleverdecode(s, cmd, **kwargs):
- if not util.binary(s):
- return dumbdecode(s, cmd, **kwargs)
- return s
-
-def cleverencode(s, cmd):
- if not util.binary(s):
- return dumbencode(s, cmd)
- return s
-
-def macdecode(s, cmd, **kwargs):
- if not util.binary(s):
- return macdumbdecode(s, cmd, **kwargs)
- return s
-
-def macencode(s, cmd):
- if not util.binary(s):
- return macdumbencode(s, cmd)
- return s
-
-_filters = {
- 'dumbdecode:': dumbdecode,
- 'dumbencode:': dumbencode,
- 'cleverdecode:': cleverdecode,
- 'cleverencode:': cleverencode,
- 'macdumbdecode:': macdumbdecode,
- 'macdumbencode:': macdumbencode,
- 'macdecode:': macdecode,
- 'macencode:': macencode,
- }
-
-def forbidnewline(ui, repo, hooktype, node, newline, **kwargs):
- halt = False
- seen = set()
- # we try to walk changesets in reverse order from newest to
- # oldest, so that if we see a file multiple times, we take the
- # newest version as canonical. this prevents us from blocking a
- # changegroup that contains an unacceptable commit followed later
- # by a commit that fixes the problem.
- tip = repo['tip']
- for rev in xrange(len(repo)-1, repo[node].rev()-1, -1):
- c = repo[rev]
- for f in c.files():
- if f in seen or f not in tip or f not in c:
- continue
- seen.add(f)
- data = c[f].data()
- if not util.binary(data) and newline in data:
- if not halt:
- ui.warn(_('Attempt to commit or push text file(s) '
- 'using %s line endings\n') %
- newlinestr[newline])
- ui.warn(_('in %s: %s\n') % (short(c.node()), f))
- halt = True
- if halt and hooktype == 'pretxnchangegroup':
- crlf = newlinestr[newline].lower()
- filter = filterstr[newline]
- ui.warn(_('\nTo prevent this mistake in your local repository,\n'
- 'add to Mercurial.ini or .hg/hgrc:\n'
- '\n'
- '[hooks]\n'
- 'pretxncommit.%s = python:hgext.win32text.forbid%s\n'
- '\n'
- 'and also consider adding:\n'
- '\n'
- '[extensions]\n'
- 'win32text =\n'
- '[encode]\n'
- '** = %sencode:\n'
- '[decode]\n'
- '** = %sdecode:\n') % (crlf, crlf, filter, filter))
- return halt
-
-def forbidcrlf(ui, repo, hooktype, node, **kwargs):
- return forbidnewline(ui, repo, hooktype, node, '\r\n', **kwargs)
-
-def forbidcr(ui, repo, hooktype, node, **kwargs):
- return forbidnewline(ui, repo, hooktype, node, '\r', **kwargs)
-
-def reposetup(ui, repo):
- if not repo.local():
- return
- for name, fn in _filters.iteritems():
- repo.adddatafilter(name, fn)
-
-def extsetup(ui):
- if ui.configbool('win32text', 'warn', True):
- ui.warn(_("win32text is deprecated: "
- "http://mercurial.selenic.com/wiki/Win32TextExtension\n"))
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.pyo
deleted file mode 100644
index fe9072d..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/win32text.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.py
deleted file mode 100644
index acca5c2..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.py
+++ /dev/null
@@ -1,1582 +0,0 @@
-""" Multicast DNS Service Discovery for Python, v0.12
- Copyright (C) 2003, Paul Scott-Murphy
-
- This module provides a framework for the use of DNS Service Discovery
- using IP multicast. It has been tested against the JRendezvous
- implementation from <a href="http://strangeberry.com">StrangeBerry</a>,
- and against the mDNSResponder from Mac OS X 10.3.8.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-"""
-
-"""0.12 update - allow selection of binding interface
- typo fix - Thanks A. M. Kuchlingi
- removed all use of word 'Rendezvous' - this is an API change"""
-
-"""0.11 update - correction to comments for addListener method
- support for new record types seen from OS X
- - IPv6 address
- - hostinfo
- ignore unknown DNS record types
- fixes to name decoding
- works alongside other processes using port 5353 (e.g. on Mac OS X)
- tested against Mac OS X 10.3.2's mDNSResponder
- corrections to removal of list entries for service browser"""
-
-"""0.10 update - Jonathon Paisley contributed these corrections:
- always multicast replies, even when query is unicast
- correct a pointer encoding problem
- can now write records in any order
- traceback shown on failure
- better TXT record parsing
- server is now separate from name
- can cancel a service browser
-
- modified some unit tests to accommodate these changes"""
-
-"""0.09 update - remove all records on service unregistration
- fix DOS security problem with readName"""
-
-"""0.08 update - changed licensing to LGPL"""
-
-"""0.07 update - faster shutdown on engine
- pointer encoding of outgoing names
- ServiceBrowser now works
- new unit tests"""
-
-"""0.06 update - small improvements with unit tests
- added defined exception types
- new style objects
- fixed hostname/interface problem
- fixed socket timeout problem
- fixed addServiceListener() typo bug
- using select() for socket reads
- tested on Debian unstable with Python 2.2.2"""
-
-"""0.05 update - ensure case insensitivty on domain names
- support for unicast DNS queries"""
-
-"""0.04 update - added some unit tests
- added __ne__ adjuncts where required
- ensure names end in '.local.'
- timeout on receiving socket for clean shutdown"""
-
-__author__ = "Paul Scott-Murphy"
-__email__ = "paul at scott dash murphy dot com"
-__version__ = "0.12"
-
-import string
-import time
-import struct
-import socket
-import threading
-import select
-import traceback
-
-__all__ = ["Zeroconf", "ServiceInfo", "ServiceBrowser"]
-
-# hook for threads
-
-globals()['_GLOBAL_DONE'] = 0
-
-# Some timing constants
-
-_UNREGISTER_TIME = 125
-_CHECK_TIME = 175
-_REGISTER_TIME = 225
-_LISTENER_TIME = 200
-_BROWSER_TIME = 500
-
-# Some DNS constants
-
-_MDNS_ADDR = '224.0.0.251'
-_MDNS_PORT = 5353;
-_DNS_PORT = 53;
-_DNS_TTL = 60 * 60; # one hour default TTL
-
-_MAX_MSG_TYPICAL = 1460 # unused
-_MAX_MSG_ABSOLUTE = 8972
-
-_FLAGS_QR_MASK = 0x8000 # query response mask
-_FLAGS_QR_QUERY = 0x0000 # query
-_FLAGS_QR_RESPONSE = 0x8000 # response
-
-_FLAGS_AA = 0x0400 # Authorative answer
-_FLAGS_TC = 0x0200 # Truncated
-_FLAGS_RD = 0x0100 # Recursion desired
-_FLAGS_RA = 0x8000 # Recursion available
-
-_FLAGS_Z = 0x0040 # Zero
-_FLAGS_AD = 0x0020 # Authentic data
-_FLAGS_CD = 0x0010 # Checking disabled
-
-_CLASS_IN = 1
-_CLASS_CS = 2
-_CLASS_CH = 3
-_CLASS_HS = 4
-_CLASS_NONE = 254
-_CLASS_ANY = 255
-_CLASS_MASK = 0x7FFF
-_CLASS_UNIQUE = 0x8000
-
-_TYPE_A = 1
-_TYPE_NS = 2
-_TYPE_MD = 3
-_TYPE_MF = 4
-_TYPE_CNAME = 5
-_TYPE_SOA = 6
-_TYPE_MB = 7
-_TYPE_MG = 8
-_TYPE_MR = 9
-_TYPE_NULL = 10
-_TYPE_WKS = 11
-_TYPE_PTR = 12
-_TYPE_HINFO = 13
-_TYPE_MINFO = 14
-_TYPE_MX = 15
-_TYPE_TXT = 16
-_TYPE_AAAA = 28
-_TYPE_SRV = 33
-_TYPE_ANY = 255
-
-# Mapping constants to names
-
-_CLASSES = { _CLASS_IN : "in",
- _CLASS_CS : "cs",
- _CLASS_CH : "ch",
- _CLASS_HS : "hs",
- _CLASS_NONE : "none",
- _CLASS_ANY : "any" }
-
-_TYPES = { _TYPE_A : "a",
- _TYPE_NS : "ns",
- _TYPE_MD : "md",
- _TYPE_MF : "mf",
- _TYPE_CNAME : "cname",
- _TYPE_SOA : "soa",
- _TYPE_MB : "mb",
- _TYPE_MG : "mg",
- _TYPE_MR : "mr",
- _TYPE_NULL : "null",
- _TYPE_WKS : "wks",
- _TYPE_PTR : "ptr",
- _TYPE_HINFO : "hinfo",
- _TYPE_MINFO : "minfo",
- _TYPE_MX : "mx",
- _TYPE_TXT : "txt",
- _TYPE_AAAA : "quada",
- _TYPE_SRV : "srv",
- _TYPE_ANY : "any" }
-
-# utility functions
-
-def currentTimeMillis():
- """Current system time in milliseconds"""
- return time.time() * 1000
-
-# Exceptions
-
-class NonLocalNameException(Exception):
- pass
-
-class NonUniqueNameException(Exception):
- pass
-
-class NamePartTooLongException(Exception):
- pass
-
-class AbstractMethodException(Exception):
- pass
-
-class BadTypeInNameException(Exception):
- pass
-
-class BadDomainName(Exception):
- def __init__(self, pos):
- Exception.__init__(self, "at position %s" % pos)
-
-class BadDomainNameCircular(BadDomainName):
- pass
-
-# implementation classes
-
-class DNSEntry(object):
- """A DNS entry"""
-
- def __init__(self, name, type, clazz):
- self.key = string.lower(name)
- self.name = name
- self.type = type
- self.clazz = clazz & _CLASS_MASK
- self.unique = (clazz & _CLASS_UNIQUE) != 0
-
- def __eq__(self, other):
- """Equality test on name, type, and class"""
- if isinstance(other, DNSEntry):
- return self.name == other.name and self.type == other.type and self.clazz == other.clazz
- return 0
-
- def __ne__(self, other):
- """Non-equality test"""
- return not self.__eq__(other)
-
- def getClazz(self, clazz):
- """Class accessor"""
- try:
- return _CLASSES[clazz]
- except:
- return "?(%s)" % (clazz)
-
- def getType(self, type):
- """Type accessor"""
- try:
- return _TYPES[type]
- except:
- return "?(%s)" % (type)
-
- def toString(self, hdr, other):
- """String representation with additional information"""
- result = "%s[%s,%s" % (hdr, self.getType(self.type), self.getClazz(self.clazz))
- if self.unique:
- result += "-unique,"
- else:
- result += ","
- result += self.name
- if other is not None:
- result += ",%s]" % (other)
- else:
- result += "]"
- return result
-
-class DNSQuestion(DNSEntry):
- """A DNS question entry"""
-
- def __init__(self, name, type, clazz):
- if not name.endswith(".local."):
- raise NonLocalNameException(name)
- DNSEntry.__init__(self, name, type, clazz)
-
- def answeredBy(self, rec):
- """Returns true if the question is answered by the record"""
- return self.clazz == rec.clazz and (self.type == rec.type or self.type == _TYPE_ANY) and self.name == rec.name
-
- def __repr__(self):
- """String representation"""
- return DNSEntry.toString(self, "question", None)
-
-
-class DNSRecord(DNSEntry):
- """A DNS record - like a DNS entry, but has a TTL"""
-
- def __init__(self, name, type, clazz, ttl):
- DNSEntry.__init__(self, name, type, clazz)
- self.ttl = ttl
- self.created = currentTimeMillis()
-
- def __eq__(self, other):
- """Tests equality as per DNSRecord"""
- if isinstance(other, DNSRecord):
- return DNSEntry.__eq__(self, other)
- return 0
-
- def suppressedBy(self, msg):
- """Returns true if any answer in a message can suffice for the
- information held in this record."""
- for record in msg.answers:
- if self.suppressedByAnswer(record):
- return 1
- return 0
-
- def suppressedByAnswer(self, other):
- """Returns true if another record has same name, type and class,
- and if its TTL is at least half of this record's."""
- if self == other and other.ttl > (self.ttl / 2):
- return 1
- return 0
-
- def getExpirationTime(self, percent):
- """Returns the time at which this record will have expired
- by a certain percentage."""
- return self.created + (percent * self.ttl * 10)
-
- def getRemainingTTL(self, now):
- """Returns the remaining TTL in seconds."""
- return max(0, (self.getExpirationTime(100) - now) / 1000)
-
- def isExpired(self, now):
- """Returns true if this record has expired."""
- return self.getExpirationTime(100) <= now
-
- def isStale(self, now):
- """Returns true if this record is at least half way expired."""
- return self.getExpirationTime(50) <= now
-
- def resetTTL(self, other):
- """Sets this record's TTL and created time to that of
- another record."""
- self.created = other.created
- self.ttl = other.ttl
-
- def write(self, out):
- """Abstract method"""
- raise AbstractMethodException
-
- def toString(self, other):
- """String representation with addtional information"""
- arg = "%s/%s,%s" % (self.ttl, self.getRemainingTTL(currentTimeMillis()), other)
- return DNSEntry.toString(self, "record", arg)
-
-class DNSAddress(DNSRecord):
- """A DNS address record"""
-
- def __init__(self, name, type, clazz, ttl, address):
- DNSRecord.__init__(self, name, type, clazz, ttl)
- self.address = address
-
- def write(self, out):
- """Used in constructing an outgoing packet"""
- out.writeString(self.address, len(self.address))
-
- def __eq__(self, other):
- """Tests equality on address"""
- if isinstance(other, DNSAddress):
- return self.address == other.address
- return 0
-
- def __repr__(self):
- """String representation"""
- try:
- return socket.inet_ntoa(self.address)
- except:
- return self.address
-
-class DNSHinfo(DNSRecord):
- """A DNS host information record"""
-
- def __init__(self, name, type, clazz, ttl, cpu, os):
- DNSRecord.__init__(self, name, type, clazz, ttl)
- self.cpu = cpu
- self.os = os
-
- def write(self, out):
- """Used in constructing an outgoing packet"""
- out.writeString(self.cpu, len(self.cpu))
- out.writeString(self.os, len(self.os))
-
- def __eq__(self, other):
- """Tests equality on cpu and os"""
- if isinstance(other, DNSHinfo):
- return self.cpu == other.cpu and self.os == other.os
- return 0
-
- def __repr__(self):
- """String representation"""
- return self.cpu + " " + self.os
-
-class DNSPointer(DNSRecord):
- """A DNS pointer record"""
-
- def __init__(self, name, type, clazz, ttl, alias):
- DNSRecord.__init__(self, name, type, clazz, ttl)
- self.alias = alias
-
- def write(self, out):
- """Used in constructing an outgoing packet"""
- out.writeName(self.alias)
-
- def __eq__(self, other):
- """Tests equality on alias"""
- if isinstance(other, DNSPointer):
- return self.alias == other.alias
- return 0
-
- def __repr__(self):
- """String representation"""
- return self.toString(self.alias)
-
-class DNSText(DNSRecord):
- """A DNS text record"""
-
- def __init__(self, name, type, clazz, ttl, text):
- DNSRecord.__init__(self, name, type, clazz, ttl)
- self.text = text
-
- def write(self, out):
- """Used in constructing an outgoing packet"""
- out.writeString(self.text, len(self.text))
-
- def __eq__(self, other):
- """Tests equality on text"""
- if isinstance(other, DNSText):
- return self.text == other.text
- return 0
-
- def __repr__(self):
- """String representation"""
- if len(self.text) > 10:
- return self.toString(self.text[:7] + "...")
- else:
- return self.toString(self.text)
-
-class DNSService(DNSRecord):
- """A DNS service record"""
-
- def __init__(self, name, type, clazz, ttl, priority, weight, port, server):
- DNSRecord.__init__(self, name, type, clazz, ttl)
- self.priority = priority
- self.weight = weight
- self.port = port
- self.server = server
-
- def write(self, out):
- """Used in constructing an outgoing packet"""
- out.writeShort(self.priority)
- out.writeShort(self.weight)
- out.writeShort(self.port)
- out.writeName(self.server)
-
- def __eq__(self, other):
- """Tests equality on priority, weight, port and server"""
- if isinstance(other, DNSService):
- return self.priority == other.priority and self.weight == other.weight and self.port == other.port and self.server == other.server
- return 0
-
- def __repr__(self):
- """String representation"""
- return self.toString("%s:%s" % (self.server, self.port))
-
-class DNSIncoming(object):
- """Object representation of an incoming DNS packet"""
-
- def __init__(self, data):
- """Constructor from string holding bytes of packet"""
- self.offset = 0
- self.data = data
- self.questions = []
- self.answers = []
- self.numQuestions = 0
- self.numAnswers = 0
- self.numAuthorities = 0
- self.numAdditionals = 0
-
- self.readHeader()
- self.readQuestions()
- self.readOthers()
-
- def readHeader(self):
- """Reads header portion of packet"""
- format = '!HHHHHH'
- length = struct.calcsize(format)
- info = struct.unpack(format, self.data[self.offset:self.offset+length])
- self.offset += length
-
- self.id = info[0]
- self.flags = info[1]
- self.numQuestions = info[2]
- self.numAnswers = info[3]
- self.numAuthorities = info[4]
- self.numAdditionals = info[5]
-
- def readQuestions(self):
- """Reads questions section of packet"""
- format = '!HH'
- length = struct.calcsize(format)
- for i in range(0, self.numQuestions):
- name = self.readName()
- info = struct.unpack(format, self.data[self.offset:self.offset+length])
- self.offset += length
-
- try:
- question = DNSQuestion(name, info[0], info[1])
- self.questions.append(question)
- except NonLocalNameException:
- pass
-
- def readInt(self):
- """Reads an integer from the packet"""
- format = '!I'
- length = struct.calcsize(format)
- info = struct.unpack(format, self.data[self.offset:self.offset+length])
- self.offset += length
- return info[0]
-
- def readCharacterString(self):
- """Reads a character string from the packet"""
- length = ord(self.data[self.offset])
- self.offset += 1
- return self.readString(length)
-
- def readString(self, len):
- """Reads a string of a given length from the packet"""
- format = '!' + str(len) + 's'
- length = struct.calcsize(format)
- info = struct.unpack(format, self.data[self.offset:self.offset+length])
- self.offset += length
- return info[0]
-
- def readUnsignedShort(self):
- """Reads an unsigned short from the packet"""
- format = '!H'
- length = struct.calcsize(format)
- info = struct.unpack(format, self.data[self.offset:self.offset+length])
- self.offset += length
- return info[0]
-
- def readOthers(self):
- """Reads the answers, authorities and additionals section of the packet"""
- format = '!HHiH'
- length = struct.calcsize(format)
- n = self.numAnswers + self.numAuthorities + self.numAdditionals
- for i in range(0, n):
- domain = self.readName()
- info = struct.unpack(format, self.data[self.offset:self.offset+length])
- self.offset += length
-
- rec = None
- if info[0] == _TYPE_A:
- rec = DNSAddress(domain, info[0], info[1], info[2], self.readString(4))
- elif info[0] == _TYPE_CNAME or info[0] == _TYPE_PTR:
- rec = DNSPointer(domain, info[0], info[1], info[2], self.readName())
- elif info[0] == _TYPE_TXT:
- rec = DNSText(domain, info[0], info[1], info[2], self.readString(info[3]))
- elif info[0] == _TYPE_SRV:
- rec = DNSService(domain, info[0], info[1], info[2], self.readUnsignedShort(), self.readUnsignedShort(), self.readUnsignedShort(), self.readName())
- elif info[0] == _TYPE_HINFO:
- rec = DNSHinfo(domain, info[0], info[1], info[2], self.readCharacterString(), self.readCharacterString())
- elif info[0] == _TYPE_AAAA:
- rec = DNSAddress(domain, info[0], info[1], info[2], self.readString(16))
- else:
- # Try to ignore types we don't know about
- # this may mean the rest of the name is
- # unable to be parsed, and may show errors
- # so this is left for debugging. New types
- # encountered need to be parsed properly.
- #
- #print "UNKNOWN TYPE = " + str(info[0])
- #raise BadTypeInNameException
- self.offset += info[3]
-
- if rec is not None:
- self.answers.append(rec)
-
- def isQuery(self):
- """Returns true if this is a query"""
- return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
-
- def isResponse(self):
- """Returns true if this is a response"""
- return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_RESPONSE
-
- def readUTF(self, offset, len):
- """Reads a UTF-8 string of a given length from the packet"""
- return self.data[offset:offset+len].decode('utf-8')
-
- def readName(self):
- """Reads a domain name from the packet"""
- result = ''
- off = self.offset
- next = -1
- first = off
-
- while 1:
- len = ord(self.data[off])
- off += 1
- if len == 0:
- break
- t = len & 0xC0
- if t == 0x00:
- result = ''.join((result, self.readUTF(off, len) + '.'))
- off += len
- elif t == 0xC0:
- if next < 0:
- next = off + 1
- off = ((len & 0x3F) << 8) | ord(self.data[off])
- if off >= first:
- raise BadDomainNameCircular(off)
- first = off
- else:
- raise BadDomainName(off)
-
- if next >= 0:
- self.offset = next
- else:
- self.offset = off
-
- return result
-
-
-class DNSOutgoing(object):
- """Object representation of an outgoing packet"""
-
- def __init__(self, flags, multicast = 1):
- self.finished = 0
- self.id = 0
- self.multicast = multicast
- self.flags = flags
- self.names = {}
- self.data = []
- self.size = 12
-
- self.questions = []
- self.answers = []
- self.authorities = []
- self.additionals = []
-
- def addQuestion(self, record):
- """Adds a question"""
- self.questions.append(record)
-
- def addAnswer(self, inp, record):
- """Adds an answer"""
- if not record.suppressedBy(inp):
- self.addAnswerAtTime(record, 0)
-
- def addAnswerAtTime(self, record, now):
- """Adds an answer if if does not expire by a certain time"""
- if record is not None:
- if now == 0 or not record.isExpired(now):
- self.answers.append((record, now))
-
- def addAuthorativeAnswer(self, record):
- """Adds an authoritative answer"""
- self.authorities.append(record)
-
- def addAdditionalAnswer(self, record):
- """Adds an additional answer"""
- self.additionals.append(record)
-
- def writeByte(self, value):
- """Writes a single byte to the packet"""
- format = '!c'
- self.data.append(struct.pack(format, chr(value)))
- self.size += 1
-
- def insertShort(self, index, value):
- """Inserts an unsigned short in a certain position in the packet"""
- format = '!H'
- self.data.insert(index, struct.pack(format, value))
- self.size += 2
-
- def writeShort(self, value):
- """Writes an unsigned short to the packet"""
- format = '!H'
- self.data.append(struct.pack(format, value))
- self.size += 2
-
- def writeInt(self, value):
- """Writes an unsigned integer to the packet"""
- format = '!I'
- self.data.append(struct.pack(format, int(value)))
- self.size += 4
-
- def writeString(self, value, length):
- """Writes a string to the packet"""
- format = '!' + str(length) + 's'
- self.data.append(struct.pack(format, value))
- self.size += length
-
- def writeUTF(self, s):
- """Writes a UTF-8 string of a given length to the packet"""
- utfstr = s.encode('utf-8')
- length = len(utfstr)
- if length > 64:
- raise NamePartTooLongException
- self.writeByte(length)
- self.writeString(utfstr, length)
-
- def writeName(self, name):
- """Writes a domain name to the packet"""
-
- try:
- # Find existing instance of this name in packet
- #
- index = self.names[name]
- except KeyError:
- # No record of this name already, so write it
- # out as normal, recording the location of the name
- # for future pointers to it.
- #
- self.names[name] = self.size
- parts = name.split('.')
- if parts[-1] == '':
- parts = parts[:-1]
- for part in parts:
- self.writeUTF(part)
- self.writeByte(0)
- return
-
- # An index was found, so write a pointer to it
- #
- self.writeByte((index >> 8) | 0xC0)
- self.writeByte(index)
-
- def writeQuestion(self, question):
- """Writes a question to the packet"""
- self.writeName(question.name)
- self.writeShort(question.type)
- self.writeShort(question.clazz)
-
- def writeRecord(self, record, now):
- """Writes a record (answer, authoritative answer, additional) to
- the packet"""
- self.writeName(record.name)
- self.writeShort(record.type)
- if record.unique and self.multicast:
- self.writeShort(record.clazz | _CLASS_UNIQUE)
- else:
- self.writeShort(record.clazz)
- if now == 0:
- self.writeInt(record.ttl)
- else:
- self.writeInt(record.getRemainingTTL(now))
- index = len(self.data)
- # Adjust size for the short we will write before this record
- #
- self.size += 2
- record.write(self)
- self.size -= 2
-
- length = len(''.join(self.data[index:]))
- self.insertShort(index, length) # Here is the short we adjusted for
-
- def packet(self):
- """Returns a string containing the packet's bytes
-
- No further parts should be added to the packet once this
- is done."""
- if not self.finished:
- self.finished = 1
- for question in self.questions:
- self.writeQuestion(question)
- for answer, time in self.answers:
- self.writeRecord(answer, time)
- for authority in self.authorities:
- self.writeRecord(authority, 0)
- for additional in self.additionals:
- self.writeRecord(additional, 0)
-
- self.insertShort(0, len(self.additionals))
- self.insertShort(0, len(self.authorities))
- self.insertShort(0, len(self.answers))
- self.insertShort(0, len(self.questions))
- self.insertShort(0, self.flags)
- if self.multicast:
- self.insertShort(0, 0)
- else:
- self.insertShort(0, self.id)
- return ''.join(self.data)
-
-
-class DNSCache(object):
- """A cache of DNS entries"""
-
- def __init__(self):
- self.cache = {}
-
- def add(self, entry):
- """Adds an entry"""
- try:
- list = self.cache[entry.key]
- except:
- list = self.cache[entry.key] = []
- list.append(entry)
-
- def remove(self, entry):
- """Removes an entry"""
- try:
- list = self.cache[entry.key]
- list.remove(entry)
- except:
- pass
-
- def get(self, entry):
- """Gets an entry by key. Will return None if there is no
- matching entry."""
- try:
- list = self.cache[entry.key]
- return list[list.index(entry)]
- except:
- return None
-
- def getByDetails(self, name, type, clazz):
- """Gets an entry by details. Will return None if there is
- no matching entry."""
- entry = DNSEntry(name, type, clazz)
- return self.get(entry)
-
- def entriesWithName(self, name):
- """Returns a list of entries whose key matches the name."""
- try:
- return self.cache[name]
- except:
- return []
-
- def entries(self):
- """Returns a list of all entries"""
- def add(x, y): return x+y
- try:
- return reduce(add, self.cache.values())
- except:
- return []
-
-
-class Engine(threading.Thread):
- """An engine wraps read access to sockets, allowing objects that
- need to receive data from sockets to be called back when the
- sockets are ready.
-
- A reader needs a handle_read() method, which is called when the socket
- it is interested in is ready for reading.
-
- Writers are not implemented here, because we only send short
- packets.
- """
-
- def __init__(self, zeroconf):
- threading.Thread.__init__(self)
- self.zeroconf = zeroconf
- self.readers = {} # maps socket to reader
- self.timeout = 5
- self.condition = threading.Condition()
- self.start()
-
- def run(self):
- while not globals()['_GLOBAL_DONE']:
- rs = self.getReaders()
- if len(rs) == 0:
- # No sockets to manage, but we wait for the timeout
- # or addition of a socket
- #
- self.condition.acquire()
- self.condition.wait(self.timeout)
- self.condition.release()
- else:
- try:
- rr, wr, er = select.select(rs, [], [], self.timeout)
- for socket in rr:
- try:
- self.readers[socket].handle_read()
- except:
- if not globals()['_GLOBAL_DONE']:
- traceback.print_exc()
- except:
- pass
-
- def getReaders(self):
- self.condition.acquire()
- result = self.readers.keys()
- self.condition.release()
- return result
-
- def addReader(self, reader, socket):
- self.condition.acquire()
- self.readers[socket] = reader
- self.condition.notify()
- self.condition.release()
-
- def delReader(self, socket):
- self.condition.acquire()
- del(self.readers[socket])
- self.condition.notify()
- self.condition.release()
-
- def notify(self):
- self.condition.acquire()
- self.condition.notify()
- self.condition.release()
-
-class Listener(object):
- """A Listener is used by this module to listen on the multicast
- group to which DNS messages are sent, allowing the implementation
- to cache information as it arrives.
-
- It requires registration with an Engine object in order to have
- the read() method called when a socket is availble for reading."""
-
- def __init__(self, zeroconf):
- self.zeroconf = zeroconf
- self.zeroconf.engine.addReader(self, self.zeroconf.socket)
-
- def handle_read(self):
- data, (addr, port) = self.zeroconf.socket.recvfrom(_MAX_MSG_ABSOLUTE)
- self.data = data
- msg = DNSIncoming(data)
- if msg.isQuery():
- # Always multicast responses
- #
- if port == _MDNS_PORT:
- self.zeroconf.handleQuery(msg, _MDNS_ADDR, _MDNS_PORT)
- # If it's not a multicast query, reply via unicast
- # and multicast
- #
- elif port == _DNS_PORT:
- self.zeroconf.handleQuery(msg, addr, port)
- self.zeroconf.handleQuery(msg, _MDNS_ADDR, _MDNS_PORT)
- else:
- self.zeroconf.handleResponse(msg)
-
-
-class Reaper(threading.Thread):
- """A Reaper is used by this module to remove cache entries that
- have expired."""
-
- def __init__(self, zeroconf):
- threading.Thread.__init__(self)
- self.zeroconf = zeroconf
- self.start()
-
- def run(self):
- while 1:
- self.zeroconf.wait(10 * 1000)
- if globals()['_GLOBAL_DONE']:
- return
- now = currentTimeMillis()
- for record in self.zeroconf.cache.entries():
- if record.isExpired(now):
- self.zeroconf.updateRecord(now, record)
- self.zeroconf.cache.remove(record)
-
-
-class ServiceBrowser(threading.Thread):
- """Used to browse for a service of a specific type.
-
- The listener object will have its addService() and
- removeService() methods called when this browser
- discovers changes in the services availability."""
-
- def __init__(self, zeroconf, type, listener):
- """Creates a browser for a specific type"""
- threading.Thread.__init__(self)
- self.zeroconf = zeroconf
- self.type = type
- self.listener = listener
- self.services = {}
- self.nextTime = currentTimeMillis()
- self.delay = _BROWSER_TIME
- self.list = []
-
- self.done = 0
-
- self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
- self.start()
-
- def updateRecord(self, zeroconf, now, record):
- """Callback invoked by Zeroconf when new information arrives.
-
- Updates information required by browser in the Zeroconf cache."""
- if record.type == _TYPE_PTR and record.name == self.type:
- expired = record.isExpired(now)
- try:
- oldrecord = self.services[record.alias.lower()]
- if not expired:
- oldrecord.resetTTL(record)
- else:
- del(self.services[record.alias.lower()])
- callback = lambda x: self.listener.removeService(x, self.type, record.alias)
- self.list.append(callback)
- return
- except:
- if not expired:
- self.services[record.alias.lower()] = record
- callback = lambda x: self.listener.addService(x, self.type, record.alias)
- self.list.append(callback)
-
- expires = record.getExpirationTime(75)
- if expires < self.nextTime:
- self.nextTime = expires
-
- def cancel(self):
- self.done = 1
- self.zeroconf.notifyAll()
-
- def run(self):
- while 1:
- event = None
- now = currentTimeMillis()
- if len(self.list) == 0 and self.nextTime > now:
- self.zeroconf.wait(self.nextTime - now)
- if globals()['_GLOBAL_DONE'] or self.done:
- return
- now = currentTimeMillis()
-
- if self.nextTime <= now:
- out = DNSOutgoing(_FLAGS_QR_QUERY)
- out.addQuestion(DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
- for record in self.services.values():
- if not record.isExpired(now):
- out.addAnswerAtTime(record, now)
- self.zeroconf.send(out)
- self.nextTime = now + self.delay
- self.delay = min(20 * 1000, self.delay * 2)
-
- if len(self.list) > 0:
- event = self.list.pop(0)
-
- if event is not None:
- event(self.zeroconf)
-
-
-class ServiceInfo(object):
- """Service information"""
-
- def __init__(self, type, name, address=None, port=None, weight=0, priority=0, properties=None, server=None):
- """Create a service description.
-
- type: fully qualified service type name
- name: fully qualified service name
- address: IP address as unsigned short, network byte order
- port: port that the service runs on
- weight: weight of the service
- priority: priority of the service
- properties: dictionary of properties (or a string holding the bytes for the text field)
- server: fully qualified name for service host (defaults to name)"""
-
- if not name.endswith(type):
- raise BadTypeInNameException
- self.type = type
- self.name = name
- self.address = address
- self.port = port
- self.weight = weight
- self.priority = priority
- if server:
- self.server = server
- else:
- self.server = name
- self.setProperties(properties)
-
- def setProperties(self, properties):
- """Sets properties and text of this info from a dictionary"""
- if isinstance(properties, dict):
- self.properties = properties
- list = []
- result = ''
- for key in properties:
- value = properties[key]
- if value is None:
- suffix = ''
- elif isinstance(value, str):
- suffix = value
- elif isinstance(value, int):
- if value:
- suffix = 'true'
- else:
- suffix = 'false'
- else:
- suffix = ''
- list.append('='.join((key, suffix)))
- for item in list:
- result = ''.join((result, struct.pack('!c', chr(len(item))), item))
- self.text = result
- else:
- self.text = properties
-
- def setText(self, text):
- """Sets properties and text given a text field"""
- self.text = text
- try:
- result = {}
- end = len(text)
- index = 0
- strs = []
- while index < end:
- length = ord(text[index])
- index += 1
- strs.append(text[index:index+length])
- index += length
-
- for s in strs:
- eindex = s.find('=')
- if eindex == -1:
- # No equals sign at all
- key = s
- value = 0
- else:
- key = s[:eindex]
- value = s[eindex+1:]
- if value == 'true':
- value = 1
- elif value == 'false' or not value:
- value = 0
-
- # Only update non-existent properties
- if key and result.get(key) == None:
- result[key] = value
-
- self.properties = result
- except:
- traceback.print_exc()
- self.properties = None
-
- def getType(self):
- """Type accessor"""
- return self.type
-
- def getName(self):
- """Name accessor"""
- if self.type is not None and self.name.endswith("." + self.type):
- return self.name[:len(self.name) - len(self.type) - 1]
- return self.name
-
- def getAddress(self):
- """Address accessor"""
- return self.address
-
- def getPort(self):
- """Port accessor"""
- return self.port
-
- def getPriority(self):
- """Pirority accessor"""
- return self.priority
-
- def getWeight(self):
- """Weight accessor"""
- return self.weight
-
- def getProperties(self):
- """Properties accessor"""
- return self.properties
-
- def getText(self):
- """Text accessor"""
- return self.text
-
- def getServer(self):
- """Server accessor"""
- return self.server
-
- def updateRecord(self, zeroconf, now, record):
- """Updates service information from a DNS record"""
- if record is not None and not record.isExpired(now):
- if record.type == _TYPE_A:
- #if record.name == self.name:
- if record.name == self.server:
- self.address = record.address
- elif record.type == _TYPE_SRV:
- if record.name == self.name:
- self.server = record.server
- self.port = record.port
- self.weight = record.weight
- self.priority = record.priority
- #self.address = None
- self.updateRecord(zeroconf, now, zeroconf.cache.getByDetails(self.server, _TYPE_A, _CLASS_IN))
- elif record.type == _TYPE_TXT:
- if record.name == self.name:
- self.setText(record.text)
-
- def request(self, zeroconf, timeout):
- """Returns true if the service could be discovered on the
- network, and updates this object with details discovered.
- """
- now = currentTimeMillis()
- delay = _LISTENER_TIME
- next = now + delay
- last = now + timeout
- result = 0
- try:
- zeroconf.addListener(self, DNSQuestion(self.name, _TYPE_ANY, _CLASS_IN))
- while self.server is None or self.address is None or self.text is None:
- if last <= now:
- return 0
- if next <= now:
- out = DNSOutgoing(_FLAGS_QR_QUERY)
- out.addQuestion(DNSQuestion(self.name, _TYPE_SRV, _CLASS_IN))
- out.addAnswerAtTime(zeroconf.cache.getByDetails(self.name, _TYPE_SRV, _CLASS_IN), now)
- out.addQuestion(DNSQuestion(self.name, _TYPE_TXT, _CLASS_IN))
- out.addAnswerAtTime(zeroconf.cache.getByDetails(self.name, _TYPE_TXT, _CLASS_IN), now)
- if self.server is not None:
- out.addQuestion(DNSQuestion(self.server, _TYPE_A, _CLASS_IN))
- out.addAnswerAtTime(zeroconf.cache.getByDetails(self.server, _TYPE_A, _CLASS_IN), now)
- zeroconf.send(out)
- next = now + delay
- delay = delay * 2
-
- zeroconf.wait(min(next, last) - now)
- now = currentTimeMillis()
- result = 1
- finally:
- zeroconf.removeListener(self)
-
- return result
-
- def __eq__(self, other):
- """Tests equality of service name"""
- if isinstance(other, ServiceInfo):
- return other.name == self.name
- return 0
-
- def __ne__(self, other):
- """Non-equality test"""
- return not self.__eq__(other)
-
- def __repr__(self):
- """String representation"""
- result = "service[%s,%s:%s," % (self.name, socket.inet_ntoa(self.getAddress()), self.port)
- if self.text is None:
- result += "None"
- else:
- if len(self.text) < 20:
- result += self.text
- else:
- result += self.text[:17] + "..."
- result += "]"
- return result
-
-
-class Zeroconf(object):
- """Implementation of Zeroconf Multicast DNS Service Discovery
-
- Supports registration, unregistration, queries and browsing.
- """
- def __init__(self, bindaddress=None):
- """Creates an instance of the Zeroconf class, establishing
- multicast communications, listening and reaping threads."""
- globals()['_GLOBAL_DONE'] = 0
- if bindaddress is None:
- self.intf = socket.gethostbyname(socket.gethostname())
- else:
- self.intf = bindaddress
- self.group = ('', _MDNS_PORT)
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
- except:
- # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
- # multicast UDP sockets (p 731, "TCP/IP Illustrated,
- # Volume 2"), but some BSD-derived systems require
- # SO_REUSEPORT to be specified explicity. Also, not all
- # versions of Python have SO_REUSEPORT available. So
- # if you're on a BSD-based system, and haven't upgraded
- # to Python 2.3 yet, you may find this library doesn't
- # work as expected.
- #
- pass
- self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 255)
- self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
- try:
- self.socket.bind(self.group)
- except:
- # Some versions of linux raise an exception even though
- # the SO_REUSE* options have been set, so ignore it
- #
- pass
- #self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.intf) + socket.inet_aton('0.0.0.0'))
- self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
-
- self.listeners = []
- self.browsers = []
- self.services = {}
- self.servicetypes = {}
-
- self.cache = DNSCache()
-
- self.condition = threading.Condition()
-
- self.engine = Engine(self)
- self.listener = Listener(self)
- self.reaper = Reaper(self)
-
- def isLoopback(self):
- return self.intf.startswith("127.0.0.1")
-
- def isLinklocal(self):
- return self.intf.startswith("169.254.")
-
- def wait(self, timeout):
- """Calling thread waits for a given number of milliseconds or
- until notified."""
- self.condition.acquire()
- self.condition.wait(timeout/1000)
- self.condition.release()
-
- def notifyAll(self):
- """Notifies all waiting threads"""
- self.condition.acquire()
- self.condition.notifyAll()
- self.condition.release()
-
- def getServiceInfo(self, type, name, timeout=3000):
- """Returns network's service information for a particular
- name and type, or None if no service matches by the timeout,
- which defaults to 3 seconds."""
- info = ServiceInfo(type, name)
- if info.request(self, timeout):
- return info
- return None
-
- def addServiceListener(self, type, listener):
- """Adds a listener for a particular service type. This object
- will then have its updateRecord method called when information
- arrives for that type."""
- self.removeServiceListener(listener)
- self.browsers.append(ServiceBrowser(self, type, listener))
-
- def removeServiceListener(self, listener):
- """Removes a listener from the set that is currently listening."""
- for browser in self.browsers:
- if browser.listener == listener:
- browser.cancel()
- del(browser)
-
- def registerService(self, info, ttl=_DNS_TTL):
- """Registers service information to the network with a default TTL
- of 60 seconds. Zeroconf will then respond to requests for
- information for that service. The name of the service may be
- changed if needed to make it unique on the network."""
- self.checkService(info)
- self.services[info.name.lower()] = info
- if self.servicetypes.has_key(info.type):
- self.servicetypes[info.type]+=1
- else:
- self.servicetypes[info.type]=1
- now = currentTimeMillis()
- nextTime = now
- i = 0
- while i < 3:
- if now < nextTime:
- self.wait(nextTime - now)
- now = currentTimeMillis()
- continue
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
- out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, ttl, info.name), 0)
- out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, ttl, info.priority, info.weight, info.port, info.server), 0)
- out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, ttl, info.text), 0)
- if info.address:
- out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, _CLASS_IN, ttl, info.address), 0)
- self.send(out)
- i += 1
- nextTime += _REGISTER_TIME
-
- def unregisterService(self, info):
- """Unregister a service."""
- try:
- del(self.services[info.name.lower()])
- if self.servicetypes[info.type]>1:
- self.servicetypes[info.type]-=1
- else:
- del self.servicetypes[info.type]
- except:
- pass
- now = currentTimeMillis()
- nextTime = now
- i = 0
- while i < 3:
- if now < nextTime:
- self.wait(nextTime - now)
- now = currentTimeMillis()
- continue
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
- out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0)
- out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, 0, info.priority, info.weight, info.port, info.name), 0)
- out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0)
- if info.address:
- out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, _CLASS_IN, 0, info.address), 0)
- self.send(out)
- i += 1
- nextTime += _UNREGISTER_TIME
-
- def unregisterAllServices(self):
- """Unregister all registered services."""
- if len(self.services) > 0:
- now = currentTimeMillis()
- nextTime = now
- i = 0
- while i < 3:
- if now < nextTime:
- self.wait(nextTime - now)
- now = currentTimeMillis()
- continue
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
- for info in self.services.values():
- out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0)
- out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, 0, info.priority, info.weight, info.port, info.server), 0)
- out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0)
- if info.address:
- out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, _CLASS_IN, 0, info.address), 0)
- self.send(out)
- i += 1
- nextTime += _UNREGISTER_TIME
-
- def checkService(self, info):
- """Checks the network for a unique service name, modifying the
- ServiceInfo passed in if it is not unique."""
- now = currentTimeMillis()
- nextTime = now
- i = 0
- while i < 3:
- for record in self.cache.entriesWithName(info.type):
- if record.type == _TYPE_PTR and not record.isExpired(now) and record.alias == info.name:
- if (info.name.find('.') < 0):
- info.name = info.name + ".[" + info.address + ":" + info.port + "]." + info.type
- self.checkService(info)
- return
- raise NonUniqueNameException
- if now < nextTime:
- self.wait(nextTime - now)
- now = currentTimeMillis()
- continue
- out = DNSOutgoing(_FLAGS_QR_QUERY | _FLAGS_AA)
- self.debug = out
- out.addQuestion(DNSQuestion(info.type, _TYPE_PTR, _CLASS_IN))
- out.addAuthorativeAnswer(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, _DNS_TTL, info.name))
- self.send(out)
- i += 1
- nextTime += _CHECK_TIME
-
- def addListener(self, listener, question):
- """Adds a listener for a given question. The listener will have
- its updateRecord method called when information is available to
- answer the question."""
- now = currentTimeMillis()
- self.listeners.append(listener)
- if question is not None:
- for record in self.cache.entriesWithName(question.name):
- if question.answeredBy(record) and not record.isExpired(now):
- listener.updateRecord(self, now, record)
- self.notifyAll()
-
- def removeListener(self, listener):
- """Removes a listener."""
- try:
- self.listeners.remove(listener)
- self.notifyAll()
- except:
- pass
-
- def updateRecord(self, now, rec):
- """Used to notify listeners of new information that has updated
- a record."""
- for listener in self.listeners:
- listener.updateRecord(self, now, rec)
- self.notifyAll()
-
- def handleResponse(self, msg):
- """Deal with incoming response packets. All answers
- are held in the cache, and listeners are notified."""
- now = currentTimeMillis()
- for record in msg.answers:
- expired = record.isExpired(now)
- if record in self.cache.entries():
- if expired:
- self.cache.remove(record)
- else:
- entry = self.cache.get(record)
- if entry is not None:
- entry.resetTTL(record)
- record = entry
- else:
- self.cache.add(record)
-
- self.updateRecord(now, record)
-
- def handleQuery(self, msg, addr, port):
- """Deal with incoming query packets. Provides a response if
- possible."""
- out = None
-
- # Support unicast client responses
- #
- if port != _MDNS_PORT:
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, 0)
- for question in msg.questions:
- out.addQuestion(question)
-
- for question in msg.questions:
- if question.type == _TYPE_PTR:
- if question.name == "_services._dns-sd._udp.local.":
- for stype in self.servicetypes.keys():
- if out is None:
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
- out.addAnswer(msg, DNSPointer("_services._dns-sd._udp.local.", _TYPE_PTR, _CLASS_IN, _DNS_TTL, stype))
- for service in self.services.values():
- if question.name == service.type:
- if out is None:
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
- out.addAnswer(msg, DNSPointer(service.type, _TYPE_PTR, _CLASS_IN, _DNS_TTL, service.name))
- else:
- try:
- if out is None:
- out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
-
- # Answer A record queries for any service addresses we know
- if question.type == _TYPE_A or question.type == _TYPE_ANY:
- for service in self.services.values():
- if service.server == question.name.lower():
- out.addAnswer(msg, DNSAddress(question.name, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
-
- service = self.services.get(question.name.lower(), None)
- if not service: continue
-
- if question.type == _TYPE_SRV or question.type == _TYPE_ANY:
- out.addAnswer(msg, DNSService(question.name, _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.priority, service.weight, service.port, service.server))
- if question.type == _TYPE_TXT or question.type == _TYPE_ANY:
- out.addAnswer(msg, DNSText(question.name, _TYPE_TXT, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.text))
- if question.type == _TYPE_SRV:
- out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
- except:
- traceback.print_exc()
-
- if out is not None and out.answers:
- out.id = msg.id
- self.send(out, addr, port)
-
- def send(self, out, addr = _MDNS_ADDR, port = _MDNS_PORT):
- """Sends an outgoing packet."""
- # This is a quick test to see if we can parse the packets we generate
- #temp = DNSIncoming(out.packet())
- try:
- self.socket.sendto(out.packet(), 0, (addr, port))
- except:
- # Ignore this, it may be a temporary loss of network connection
- pass
-
- def close(self):
- """Ends the background threads, and prevent this instance from
- servicing further queries."""
- if globals()['_GLOBAL_DONE'] == 0:
- globals()['_GLOBAL_DONE'] = 1
- self.notifyAll()
- self.engine.notify()
- self.unregisterAllServices()
- self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
- self.socket.close()
-
-# Test a few module features, including service registration, service
-# query (for Zoe), and service unregistration.
-
-if __name__ == '__main__':
- print "Multicast DNS Service Discovery for Python, version", __version__
- r = Zeroconf()
- print "1. Testing registration of a service..."
- desc = {'version':'0.10','a':'test value', 'b':'another value'}
- info = ServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local.", socket.inet_aton("127.0.0.1"), 1234, 0, 0, desc)
- print " Registering service..."
- r.registerService(info)
- print " Registration done."
- print "2. Testing query of service information..."
- print " Getting ZOE service:", str(r.getServiceInfo("_http._tcp.local.", "ZOE._http._tcp.local."))
- print " Query done."
- print "3. Testing query of own service..."
- print " Getting self:", str(r.getServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local."))
- print " Query done."
- print "4. Testing unregister of service information..."
- r.unregisterService(info)
- print " Unregister done."
- r.close()
-
-# no-check-code
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.pyo
deleted file mode 100644
index 339a003..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/Zeroconf.pyo
+++ /dev/null
Binary files differ
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.py
deleted file mode 100644
index 60185c7..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# zeroconf.py - zeroconf support for Mercurial
-#
-# Copyright 2005-2007 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.
-
-'''discover and advertise repositories on the local network
-
-Zeroconf-enabled repositories will be announced in a network without
-the need to configure a server or a service. They can be discovered
-without knowing their actual IP address.
-
-To allow other people to discover your repository using run
-:hg:`serve` in your repository::
-
- $ cd test
- $ hg serve
-
-You can discover Zeroconf-enabled repositories by running
-:hg:`paths`::
-
- $ hg paths
- zc-test = http://example.com:8000/test
-'''
-
-import socket, time, os
-
-import Zeroconf
-from mercurial import ui, hg, encoding, util
-from mercurial import extensions
-from mercurial.hgweb import hgweb_mod
-from mercurial.hgweb import hgwebdir_mod
-
-# publish
-
-server = None
-localip = None
-
-def getip():
- # finds external-facing interface without sending any packets (Linux)
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- s.connect(('1.0.0.1', 0))
- ip = s.getsockname()[0]
- return ip
- except:
- pass
-
- # Generic method, sometimes gives useless results
- try:
- dumbip = socket.gethostbyaddr(socket.gethostname())[2][0]
- if not dumbip.startswith('127.') and ':' not in dumbip:
- return dumbip
- except (socket.gaierror, socket.herror):
- dumbip = '127.0.0.1'
-
- # works elsewhere, but actually sends a packet
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- s.connect(('1.0.0.1', 1))
- ip = s.getsockname()[0]
- return ip
- except:
- pass
-
- return dumbip
-
-def publish(name, desc, path, port):
- global server, localip
- if not server:
- ip = getip()
- if ip.startswith('127.'):
- # if we have no internet connection, this can happen.
- return
- localip = socket.inet_aton(ip)
- server = Zeroconf.Zeroconf(ip)
-
- hostname = socket.gethostname().split('.')[0]
- host = hostname + ".local"
- name = "%s-%s" % (hostname, name)
-
- # advertise to browsers
- svc = Zeroconf.ServiceInfo('_http._tcp.local.',
- name + '._http._tcp.local.',
- server = host,
- port = port,
- properties = {'description': desc,
- 'path': "/" + path},
- address = localip, weight = 0, priority = 0)
- server.registerService(svc)
-
- # advertise to Mercurial clients
- svc = Zeroconf.ServiceInfo('_hg._tcp.local.',
- name + '._hg._tcp.local.',
- server = host,
- port = port,
- properties = {'description': desc,
- 'path': "/" + path},
- address = localip, weight = 0, priority = 0)
- server.registerService(svc)
-
-class hgwebzc(hgweb_mod.hgweb):
- def __init__(self, repo, name=None, baseui=None):
- super(hgwebzc, self).__init__(repo, name=name, baseui=baseui)
- name = self.reponame or os.path.basename(self.repo.root)
- path = self.repo.ui.config("web", "prefix", "").strip('/')
- desc = self.repo.ui.config("web", "description", name)
- publish(name, desc, path,
- util.getport(self.repo.ui.config("web", "port", 8000)))
-
-class hgwebdirzc(hgwebdir_mod.hgwebdir):
- def __init__(self, conf, baseui=None):
- super(hgwebdirzc, self).__init__(conf, baseui=baseui)
- prefix = self.ui.config("web", "prefix", "").strip('/') + '/'
- for repo, path in self.repos:
- u = self.ui.copy()
- u.readconfig(os.path.join(path, '.hg', 'hgrc'))
- name = os.path.basename(repo)
- path = (prefix + repo).strip('/')
- desc = u.config('web', 'description', name)
- publish(name, desc, path, util.getport(u.config("web", "port", 8000)))
-
-# listen
-
-class listener(object):
- def __init__(self):
- self.found = {}
- def removeService(self, server, type, name):
- if repr(name) in self.found:
- del self.found[repr(name)]
- def addService(self, server, type, name):
- self.found[repr(name)] = server.getServiceInfo(type, name)
-
-def getzcpaths():
- ip = getip()
- if ip.startswith('127.'):
- return
- server = Zeroconf.Zeroconf(ip)
- l = listener()
- Zeroconf.ServiceBrowser(server, "_hg._tcp.local.", l)
- time.sleep(1)
- server.close()
- for value in l.found.values():
- name = value.name[:value.name.index('.')]
- url = "http://%s:%s%s" % (socket.inet_ntoa(value.address), value.port,
- value.properties.get("path", "/"))
- yield "zc-" + name, url
-
-def config(orig, self, section, key, default=None, untrusted=False):
- if section == "paths" and key.startswith("zc-"):
- for name, path in getzcpaths():
- if name == key:
- return path
- return orig(self, section, key, default, untrusted)
-
-def configitems(orig, self, section, untrusted=False):
- repos = orig(self, section, untrusted)
- if section == "paths":
- repos += getzcpaths()
- return repos
-
-def defaultdest(orig, source):
- for name, path in getzcpaths():
- if path == source:
- return name.encode(encoding.encoding)
- return orig(source)
-
-extensions.wrapfunction(ui.ui, 'config', config)
-extensions.wrapfunction(ui.ui, 'configitems', configitems)
-extensions.wrapfunction(hg, 'defaultdest', defaultdest)
-hgweb_mod.hgweb = hgwebzc
-hgwebdir_mod.hgwebdir = hgwebdirzc
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.pyo b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.pyo
deleted file mode 100644
index 82e5bf4..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/zeroconf/__init__.pyo
+++ /dev/null
Binary files differ