cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# This program is free software; you can redistribute it and/or modify
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# it under the terms of the GNU General Public License version 2
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# as published by the Free Software Foundation.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# This program is distributed in the hope that it will be useful,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# but WITHOUT ANY WARRANTY; without even the implied warranty of
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# GNU General Public License for more details.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# You should have received a copy of the GNU General Public License
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# along with this program; if not, write to the Free Software
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe# Copyright 2008, 2011 Richard Lowe
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore# Copyright 2014 Garrett D'Amore <garrett@damore.org>
e55874358132a4aa6132178335bf567ca79c87c3Joshua M. Clulow# Copyright (c) 2014, Joyent, Inc.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe'''OpenSolaris extensions to Mercurial
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe This extension contains a number of commands to help you work with
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowethe OpenSolaris consolidations. It provides commands to check your
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowechanges against the various style rules used for OpenSolaris, to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowebackup and restore your changes, to generate code reviews, and to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweprepare your changes for integration.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard LoweThe Parent
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe To provide a uniform notion of parent workspace regardless of
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowefilesystem-based access, Cadmium uses the highest numbered changeset
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweon the current branch that is also in the parent workspace to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowerepresent the parent workspace.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard LoweThe Active List
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Many Cadmium commands operate on the active list, the set of
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowefiles ('active files') you have changed in this workspace in relation
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweto its parent workspace, and the metadata (commentary, primarily)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweassociated with those changes.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard LoweNOT Files
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Many of Cadmium's commands to check that your work obeys the
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowevarious stylistic rules of the OpenSolaris consolidations (such as
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowethose run by 'hg nits') allow files to be excluded from this checking
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweby means of NOT files kept in the .hg/cdm/ directory of the Mercurial
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowerepository for one-time exceptions, and in the exception_lists
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowedirectory at the repository root for permanent exceptions. (For ON,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowethese would mean one in $CODEMGR_WS and one in
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe$CODEMGR_WS/usr/closed).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe These files are in the same format as the Mercurial hgignore
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowefile, a description of which is available in the hgignore(5) manual
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowepage.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard LoweCommon Tasks
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Show diffs relative to parent workspace - pdiffs
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Check source style rules - nits
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Run pre-integration checks - pbchk
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Collapse all your changes into a single changeset - recommit
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe'''
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweimport atexit, os, re, sys, stat, termios
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# Adjust the load path based on the location of cdm.py and the version
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# of python into which it is being loaded. This assumes the normal
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# onbld directory structure, where cdm.py is in
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# lib/python(version)?/onbld/hgext/. If that changes so too must
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# this.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# This and the case below are not equivalent. In this case we may be
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# loading a cdm.py in python2.X/ via the lib/python/ symlink but need
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# python2.Y in sys.path.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowesys.path.insert(1, os.path.join(os.path.dirname(__file__), "..", "..", "..",
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe "python%d.%d" % sys.version_info[:2]))
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe#
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# Add the relative path from cdm.py to usr/src/tools to the load path,
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# such that a cdm.py loaded from the source tree uses the modules also
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# within the source tree.
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe#
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowesys.path.insert(2, os.path.join(os.path.dirname(__file__), "..", ".."))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonfrom onbld.Scm import Version
e55874358132a4aa6132178335bf567ca79c87c3Joshua M. Clulowfrom onbld.Scm import Ignore
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonfrom mercurial import util
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsontry:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson Version.check_version()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonexcept Version.VersionMismatch, badversion:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson raise util.Abort("Version Mismatch:\n %s\n" % badversion)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
e55874358132a4aa6132178335bf567ca79c87c3Joshua M. Clulowfrom mercurial import cmdutil, node, patch
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowefrom onbld.Scm.WorkSpace import WorkSpace, WorkList
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonfrom onbld.Scm.Backup import CdmBackup
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonfrom onbld.Checks import Cddl, Comments, Copyright, CStyle, HdrChk
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorefrom onbld.Checks import JStyle, Keywords, ManLint, Mapfile
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef yes_no(ui, msg, default):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if default:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson prompt = ' [Y/n]:'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson defanswer = 'y'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson prompt = ' [y/N]:'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson defanswer = 'n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe if Version.at_least("1.4"):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe index = ui.promptchoice(msg + prompt, ['&yes', '&no'],
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe default=['y', 'n'].index(defanswer))
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe resp = ('y', 'n')[index]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe resp = ui.prompt(msg + prompt, ['&yes', '&no'], default=defanswer)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe return resp[0] in ('Y', 'y')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowedef buildfilelist(ws, parent, files):
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe '''Build a list of files in which we're interested.
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe If no files are specified take files from the active list relative
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe to 'parent'.
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe Return a list of 2-tuples the first element being a path relative
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe to the current directory and the second an entry from the active
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe list, or None if an explicit file list was given.'''
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe if files:
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe return [(path, None) for path in sorted(files)]
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson else:
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe active = ws.active(parent=parent)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe return [(ws.filepath(e.name), e) for e in sorted(active)]
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowebuildfilelist = util.cachefunc(buildfilelist)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef not_check(repo, cmd):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson '''return a function which returns boolean indicating whether a file
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson should be skipped for CMD.'''
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami #
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami # The ignore routines need a canonical path to the file (relative to the
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami # repo root), whereas the check commands get paths relative to the cwd.
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami #
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami # Wrap our argument such that the path is canonified before it is checked.
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami #
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami def canonified_check(ignfunc):
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami def f(path):
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami cpath = util.canonpath(repo.root, repo.getcwd(), path)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami return ignfunc(cpath)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami return f
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami ignorefiles = []
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe for f in [repo.join('cdm/%s.NOT' % cmd),
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe repo.wjoin('exception_lists/%s' % cmd)]:
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami if os.path.exists(f):
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe ignorefiles.append(f)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami if ignorefiles:
e55874358132a4aa6132178335bf567ca79c87c3Joshua M. Clulow ign = Ignore.ignore(repo.root, ignorefiles)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami return canonified_check(ign)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson else:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson return util.never
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowedef abort_if_dirty(ws):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe '''Abort if the workspace has uncommitted changes, merges,
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe branches, or has Mq patches applied'''
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if ws.modified():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace has uncommitted changes')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if ws.merged():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace contains uncommitted merge')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if ws.branched():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace contains uncommitted branch')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if ws.mq_applied():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace has Mq patches applied')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Adding a reference to WorkSpace from a repo causes a circular reference
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# repo <-> WorkSpace.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# This prevents repo, WorkSpace and members thereof from being garbage
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# collected. Since transactions are aborted when the transaction object
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# is collected, and localrepo holds a reference to the most recently created
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# transaction, this prevents transactions from cleanly aborting.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Instead, we hold the repo->WorkSpace association in a dictionary, breaking
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# that dependence.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonwslist = {}
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef reposetup(ui, repo):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if repo.local() and repo not in wslist:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson wslist[repo] = WorkSpace(repo)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe if ui.interactive() and sys.stdin.isatty():
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe ui.setconfig('hooks', 'preoutgoing.cdm_pbconfirm',
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe 'python:hgext_cdm.pbconfirm')
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef pbconfirm(ui, repo, hooktype, source):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson def wrapper(settings=None):
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, settings)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if source == 'push':
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if not yes_no(ui, "Are you sure you wish to push?", False):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson return 1
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson else:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson settings = termios.tcgetattr(sys.stdin.fileno())
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe orig = list(settings)
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe atexit.register(wrapper, orig)
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe settings[3] = settings[3] & (~termios.ISIG) # c_lflag
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, settings)
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_pdiffs(ui, repo, *pats, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''diff workspace against its parent
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Show differences between this workspace and its parent workspace
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe in the same manner as 'hg diff'.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For a description of the changeset used to represent the parent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe workspace, see The Parent in the extension documentation ('hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe act = wslist[repo].active(opts.get('parent'))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if not act.revs:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe return
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # If no patterns were specified, either explicitly or via -I or -X
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # use the active list files to avoid a workspace walk.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if pats or opts.get('include') or opts.get('exclude'):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe matchfunc = wslist[repo].matcher(pats=pats, opts=opts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe else:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe matchfunc = wslist[repo].matcher(files=act.files())
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe opts = patch.diffopts(ui, opts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe diffs = wslist[repo].diff(act.parenttip.node(), act.localtip.node(),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe match=matchfunc, opts=opts)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if diffs:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(diffs)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_list(ui, repo, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''list active files (those changed in this workspace)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Display a list of files changed in this workspace as compared to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe its parent workspace.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe File names are displayed one-per line, grouped by manner in which
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe they changed (added, modified, removed). Information about
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe renames or copies is output in parentheses following the file
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe name.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For a description of the changeset used to represent the parent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe workspace, see The Parent in the extension documentation ('hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Output can be filtered by change type with --added, --modified,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe and --removed. By default, all files are shown.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson act = wslist[repo].active(opts['parent'])
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wanted = set(x for x in ('added', 'modified', 'removed') if opts[x])
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe changes = {}
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for entry in act:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if wanted and (entry.change not in wanted):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if entry.change not in changes:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe changes[entry.change] = []
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe changes[entry.change].append(entry)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for change in sorted(changes.keys()):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write(change + ':\n')
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for entry in sorted(changes[change]):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if entry.is_renamed():
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write('\t%s (renamed from %s)\n' % (entry.name,
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe entry.parentname))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe elif entry.is_copied():
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write('\t%s (copied from %s)\n' % (entry.name,
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe entry.parentname))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write('\t%s\n' % entry.name)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_bugs(ui, repo, parent=None):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''show all bug IDs referenced in changeset comments'''
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson act = wslist[repo].active(parent)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for elt in set(filter(Comments.isBug, act.comments())):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(elt + '\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_comments(ui, repo, parent=None):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''show changeset commentary for all active changesets'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson act = wslist[repo].active(parent)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for elt in act.comments():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(elt + '\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_renamed(ui, repo, parent=None):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''show renamed active files
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Renamed files are shown in the format::
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe new-name old-name
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe One pair per-line.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson act = wslist[repo].active(parent)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for entry in sorted(filter(lambda x: x.is_renamed(), act)):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('%s %s\n' % (entry.name, entry.parentname))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_comchk(ui, repo, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active changeset comment formatting
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that active changeset comments conform to O/N rules.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Each comment line must contain either one bug or ARC case ID
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe followed by its synopsis, or credit an external contributor.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson active = wslist[repo].active(opts.get('parent'))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Comments check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson check_db = not opts.get('nocheck')
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe return Comments.comchk(active.comments(), check_db=check_db, output=ui)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_cddlchk(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check for a valid CDDL header comment in all active files.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check active files for a valid Common Development and Distribution
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe License (CDDL) block comment.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Newly added files are checked for a copy of the CDDL header
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe comment. Modified files are only checked if they contain what
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe appears to be an existing CDDL header comment.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the cddlchk.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'cddlchk')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson lenient = True
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ui.write('CDDL block check:\n')
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif e and e.is_added():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson lenient = False
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson lenient = True
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh = open(f, 'r')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret |= Cddl.cddlchk(fh, lenient=lenient, output=ui)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson fh.close()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoredef cdm_manlintchk(ui, repo, *args, **opts):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore '''check for mandoc lint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Check for man page formatting errors.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Files can be excluded from this check using the manlint.NOT
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore file. See NOT Files in the extension documentation ('hg help
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore cdm').
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore '''
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore exclude = not_check(repo, 'manlint')
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ret = 0
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore # Man pages are identified as having a suffix starting with a digit.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ManfileRE = re.compile(r'.*\.[0-9][a-z]*$', re.IGNORECASE)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ui.write('Man format check:\n')
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore for f, e in filelist:
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore if e and e.is_removed():
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore continue
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore elif (not ManfileRE.match(f)):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore continue
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore elif (e or opts.get('honour_nots')) and exclude(f):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ui.status('Skipping %s...\n' % f)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore continue
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore fh = open(f, 'r')
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ret |= ManLint.manlint(fh, output=ui, picky=True)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore fh.close()
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore return ret
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahramidef cdm_mapfilechk(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check for a valid mapfile header block in active files
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami Check that all link-editor mapfiles contain the standard mapfile
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami header comment directing the reader to the document containing
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Solaris object versioning rules (README.mapfile).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the mapfilechk.NOT
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe file. See NOT Files in the extension documentation ('hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'mapfilechk')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ret = 0
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # We are interested in examining any file that has the following
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # in its final path segment:
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # - Contains the word 'mapfile'
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # - Begins with 'map.'
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # - Ends with '.map'
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # We don't want to match unless these things occur in final path segment
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # because directory names with these strings don't indicate a mapfile.
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami # We also ignore files with suffixes that tell us that the files
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami # are not mapfiles.
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami MapfileRE = re.compile(r'.*((mapfile[^/]*)|(/map\.+[^/]*)|(\.map))$',
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe re.IGNORECASE)
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami NotMapSuffixRE = re.compile(r'.*\.[ch]$', re.IGNORECASE)
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami ui.write('Mapfile comment check:\n')
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami if e and e.is_removed():
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami continue
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami elif (not MapfileRE.match(f)) or NotMapSuffixRE.match(f):
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami continue
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami elif (e or opts.get('honour_nots')) and exclude(f):
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami ui.status('Skipping %s...\n' % f)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami continue
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami fh = open(f, 'r')
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami ret |= Mapfile.mapfilechk(fh, output=ui)
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami fh.close()
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami return ret
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_copyright(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check each active file for a current and correct copyright notice
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that all active files have a correctly formed copyright
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe notice containing the current year.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See the Non-Formatting Considerations section of the OpenSolaris
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Developer's Reference for more info on the correct form of
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe copyright notice.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe (http://hub.opensolaris.org/bin/view/Community+Group+on/devref_7#H723NonFormattingConsiderations)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the copyright.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'copyright')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Copyright check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh = open(f, 'r')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret |= Copyright.copyright(fh, output=ui)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson fh.close()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_hdrchk(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active C header files conform to the O/N header rules
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that any added or modified C header files conform to the O/N
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe header rules.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See the section 'HEADER STANDARDS' in the hdrchk(1) manual page
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe for more information on the rules for O/N header file formatting.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the hdrchk.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'hdrchk')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Header format check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif not f.endswith('.h'):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh = open(f, 'r')
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ret |= HdrChk.hdrchk(fh, lenient=True, output=ui)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh.close()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_cstyle(ui, repo, *args, **opts):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''check active C source files conform to the C Style Guide
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that any added or modified C source file conform to the C
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Style Guide.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See the C Style Guide for more information about correct C source
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe formatting.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe (http://hub.opensolaris.org/bin/download/Community+Group+on/WebHome/cstyle.ms.pdf)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the cstyle.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'cstyle')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('C style check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif not (f.endswith('.c') or f.endswith('.h')):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh = open(f, 'r')
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ret |= CStyle.cstyle(fh, output=ui,
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson picky=True, check_posix_types=True,
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson check_continuation=True)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh.close()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_jstyle(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active Java source files for common stylistic errors
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the jstyle.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'jstyle')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Java style check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif not f.endswith('.java'):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh = open(f, 'r')
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ret |= JStyle.jstyle(fh, output=ui, picky=True)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh.close()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_permchk(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check the permissions of each active file
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that the file permissions of each added or modified file do not
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe contain the executable bit.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the permchk.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'permchk')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exeFiles = []
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('File permission check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson mode = stat.S_IMODE(os.stat(f)[stat.ST_MODE])
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if mode & stat.S_IEXEC:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson exeFiles.append(f)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if len(exeFiles) > 0:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: the following active file(s) have executable mode '
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '(+x) permission set,\nremove unless intentional:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for fname in exeFiles:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(" %s\n" % fname)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return len(exeFiles) > 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_tagchk(ui, repo, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check modification of workspace tags
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check for any modification of the repository's .hgtags file.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe With the exception of the gatekeepers, nobody should introduce or
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe modify a repository's tags.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson active = wslist[repo].active(opts.get('parent'))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Checking for new tags:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if ".hgtags" in active:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson tfile = wslist[repo].filepath('.hgtags')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ptip = active.parenttip.rev()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: Workspace contains new non-local tags.\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'Only gatekeepers should add or modify such tags.\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'Use the following commands to revert these changes:\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ' hg revert -r%d %s\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ' hg commit %s\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'You should also recommit before integration\n' %
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson (ptip, tfile, tfile))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_branchchk(ui, repo, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check for changes in number or name of branches
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that the workspace contains only a single head, that it is
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe on the branch 'default', and that no new branches have been
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe introduced.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Checking for multiple heads (or branches):\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson heads = set(repo.heads())
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe parents = set([x.node() for x in wslist[repo].workingctx().parents()])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # We care if there's more than one head, and those heads aren't
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # identical to the dirstate parents (if they are identical, it's
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # an uncommitted merge which mergechk will catch, no need to
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # complain twice).
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if len(heads) > 1 and heads != parents:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Workspace has multiple heads (or branches):\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for head in [repo.changectx(head) for head in heads]:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(" %d:%s\t%s\n" %
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson (head.rev(), str(head), head.description().splitlines()[0]))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('You must merge and recommit.\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('\nChecking for branch changes:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
ca0ac9825c08d047acccfa75c372cc572a321063mjnelson if repo.dirstate.branch() != 'default':
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write("Warning: Workspace tip has named branch: '%s'\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "Only gatekeepers should push new branches.\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "Use the following commands to restore the branch name:\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg branch [-f] default\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg commit\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "You should also recommit before integration\n" %
ca0ac9825c08d047acccfa75c372cc572a321063mjnelson (repo.dirstate.branch()))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson branches = repo.branchtags().keys()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if len(branches) > 1:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: Workspace has named branches:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for t in branches:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if t == 'default':
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write("\t%s\n" % t)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write("Only gatekeepers should push new branches.\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "Use the following commands to remove extraneous branches.\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg branch [-f] default\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg commit"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "You should also recommit before integration\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_keywords(ui, repo, *args, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active files for SCCS keywords
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that any added or modified files do not contain SCCS keywords
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe (#ident lines, etc.).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the keywords.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe exclude = not_check(repo, 'keywords')
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Keywords check:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe for f, e in filelist:
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if e and e.is_removed():
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson continue
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ui.status('Skipping %s...\n' % f)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson fh = open(f, 'r')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret |= Keywords.keywords(fh, output=ui)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson fh.close()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# NB:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# There's no reason to hook this up as an invokable command, since
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# we have 'hg status', but it must accept the same arguments.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_outchk(ui, repo, **opts):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Warn the user if they have uncommitted changes'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Checking for uncommitted changes:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson st = wslist[repo].modified()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if st:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: the following files have uncommitted changes:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for elt in st:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(' %s\n' % elt)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_mergechk(ui, repo, **opts):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Warn the user if their workspace contains merges'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson active = wslist[repo].active(opts.get('parent'))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Checking for merges:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson merges = filter(lambda x: len(x.parents()) == 2 and x.parents()[1],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson active.revs)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if merges:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Workspace contains the following merges:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for rev in merges:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson desc = rev.description().splitlines()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write(' %s:%s\t%s\n' %
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson (rev.rev() or "working", str(rev),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson desc and desc[0] or "*** uncommitted change ***"))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef run_checks(ws, cmds, *args, **opts):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Run CMDS (with OPTS) over active files in WS'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for cmd in cmds:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson name = cmd.func_name.split('_')[1]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not ws.ui.configbool('cdm', name, True):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ws.ui.status('Skipping %s check...\n' % name)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ws.ui.pushbuffer()
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe result = cmd(ws.ui, ws.repo, honour_nots=True, *args, **opts)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe output = ws.ui.popbuffer()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret |= result
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not ws.ui.quiet or result != 0:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ws.ui.write(output, '\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelsondef cdm_nits(ui, repo, *args, **opts):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''check for stylistic nits in active files
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check each active file for basic stylistic errors.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe The following checks are run over each active file (see 'hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe <check>' for more information about each):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - copyright (copyright statements)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - cstyle (C source style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - hdrchk (C header style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - jstyle (java source style)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore - manlint (man page formatting)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - mapfilechk (link-editor mapfiles)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - permchk (file permissions)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - keywords (SCCS keywords)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe With the global -q/--quiet option, only provide output for those
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe checks which fail.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe cmds = [cdm_copyright,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_cstyle,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_hdrchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_jstyle,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore cmd_manlintchk,
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami cdm_mapfilechk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_permchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_keywords]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson return run_checks(wslist[repo], cmds, *args, **opts)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
05945f8bf9e004c8feb0e1f01f574f2cbb5a485bRich Lowedef cdm_pbchk(ui, repo, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''run pre-integration checks on this workspace
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check this workspace for common errors prior to integration.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe The following checks are run over the active list (see 'hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe <check>' for more information about each):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - branchchk (addition/modification of branches)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - comchk (changeset descriptions)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - copyright (copyright statements)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - cstyle (C source style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - hdrchk (C header style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - jstyle (java source style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - keywords (SCCS keywords)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore - manlint (man page formatting)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - mapfilechk (link-editor mapfiles)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - permchk (file permissions)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - tagchk (addition/modification of tags)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Additionally, the workspace is checked for outgoing merges (which
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe should be removed with 'hg recommit'), and uncommitted changes.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe With the global -q/--quiet option, only provide output for those
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe checks which fail.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # The current ordering of these is that the commands from cdm_nits
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe # run first in the same order as they would in cdm_nits, then the
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe # pbchk specifics are run.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe cmds = [cdm_copyright,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_cstyle,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_hdrchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_jstyle,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore cdm_manlintchk,
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami cdm_mapfilechk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_permchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_keywords,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_comchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_tagchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_branchchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_outchk,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cdm_mergechk]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
05945f8bf9e004c8feb0e1f01f574f2cbb5a485bRich Lowe return run_checks(wslist[repo], cmds, **opts)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_recommit(ui, repo, **opts):
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp '''replace outgoing changesets with a single equivalent changeset
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp Replace all outgoing changesets with a single changeset containing
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp equivalent changes. This removes uninteresting changesets created
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp during development that would only serve as noise in the gate.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp Any changed file that is now identical in content to that in the
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp parent workspace (whether identical in history or otherwise) will
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp not be included in the new changeset. Any merges information will
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp also be removed.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp If no files are changed in comparison to the parent workspace, the
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp outgoing changesets will be removed, but no new changeset created.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit will refuse to run if the workspace contains more than
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp one outgoing head, even if those heads are on the same branch. To
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit with only one branch containing outgoing changesets, your
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp workspace must be on that branch and at that branch head.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit will prompt you to take a backup if your workspace has
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp been changed since the last backup was taken. In almost all
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp cases, you should allow it to take one (the default).
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit cannot be run if the workspace contains any uncommitted
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp changes, applied Mq patches, or has multiple outgoing heads (or
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp branches).
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp '''
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp ws = wslist[repo]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not os.getcwd().startswith(repo.root):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson raise util.Abort('recommit is not safe to run with -R')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp abort_if_dirty(ws)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe wlock = repo.wlock()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe lock = repo.lock()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe try:
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp parent = ws.parent(opts['parent'])
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp between = repo.changelog.nodesbetween(ws.findoutgoing(parent))[2]
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp heads = set(between) & set(repo.heads())
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp if len(heads) > 1:
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp ui.warn('Workspace has multiple outgoing heads (or branches):\n')
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp for head in sorted(map(repo.changelog.rev, heads), reverse=True):
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp ui.warn('\t%d\n' % head)
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp raise util.Abort('you must merge before recommitting')
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # We can safely use the worklist here, as we know (from the
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # abort_if_dirty() check above) that the working copy has not been
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # modified.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp active = ws.active(parent)
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp if filter(lambda b: len(b.parents()) > 1, active.bases()):
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp raise util.Abort('Cannot recommit a merge of two non-outgoing '
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp 'changesets')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if len(active.revs) <= 0:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort("no changes to recommit")
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if len(active.files()) <= 0:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe ui.warn("Recommitting %d active changesets, but no active files\n" %
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe len(active.revs))
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe #
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # During the course of a recommit, any file bearing a name
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # matching the source name of any renamed file will be
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # clobbered by the operation.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe #
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # As such, we ask the user before proceeding.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe #
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe bogosity = [f.parentname for f in active if f.is_renamed() and
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe os.path.exists(repo.wjoin(f.parentname))]
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if bogosity:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe ui.warn("The following file names are the original name of a "
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe "rename and also present\n"
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe "in the working directory:\n")
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe for fname in bogosity:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe ui.warn(" %s\n" % fname)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if not yes_no(ui, "These files will be removed by recommit."
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe " Continue?",
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe False):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort("recommit would clobber files")
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe user = opts['user'] or ui.username()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe comments = '\n'.join(active.comments())
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe message = cmdutil.logmessage(opts) or ui.edit(comments, user)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if not message:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('empty commit message')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp bk = CdmBackup(ui, ws, backup_name(repo.root))
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if bk.need_backup():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if yes_no(ui, 'Do you want to backup files first?', True):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe bk.backup()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe oldtags = repo.tags()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe clearedtags = [(name, nd, repo.changelog.rev(nd), local)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe for name, nd, local in active.tags()]
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp ws.squishdeltas(active, message, user=user)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe finally:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe lock.release()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe wlock.release()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if clearedtags:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write("Removed tags:\n")
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe for name, nd, rev, local in sorted(clearedtags,
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe key=lambda x: x[0].lower()):
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe ui.write(" %5s:%s:\t%s%s\n" % (rev, node.short(nd),
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe name, (local and ' (local)' or '')))
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe for ntag, nnode in sorted(repo.tags().items(),
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe key=lambda x: x[0].lower()):
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe if ntag in oldtags and ntag != "tip":
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe if oldtags[ntag] != nnode:
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe ui.write("tag '%s' now refers to revision %d:%s\n" %
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe (ntag, repo.changelog.rev(nnode),
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe node.short(nnode)))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef do_eval(cmd, files, root, changedir=True):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not changedir:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.chdir(root)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for path in sorted(files):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson dirn, base = os.path.split(path)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if changedir:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.chdir(os.path.join(root, dirn))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.putenv('workspace', root)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.putenv('filepath', path)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.putenv('dir', dirn)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.putenv('file', base)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson os.system(cmd)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_eval(ui, repo, *command, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''run specified command for each active file
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Run the command specified on the command line for each active
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe file, with the following variables present in the environment:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$file: - active file basename.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$dir: - active file dirname.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$filepath: - path from workspace root to active file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$workspace: - full path to workspace root.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For example:
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe hg eval 'echo $dir; hg log -l3 $file'
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe will show the last the 3 log entries for each active file,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe preceded by its directory.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson act = wslist[repo].active(opts['parent'])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cmd = ' '.join(command)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson files = [x.name for x in act if not x.is_removed()]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson do_eval(cmd, files, repo.root, not opts['remain'])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_apply(ui, repo, *command, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''apply specified command to all active files
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Run the command specified on the command line over each active
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe file.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For example 'hg apply "wc -l"' will output a count of the lines in
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe each active file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson act = wslist[repo].active(opts['parent'])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if opts['remain']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson appnd = ' $filepath'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson appnd = ' $file'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson cmd = ' '.join(command) + appnd
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson files = [x.name for x in act if not x.is_removed()]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson do_eval(cmd, files, repo.root, not opts['remain'])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowedef cdm_reparent(ui, repo, parent):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe '''reparent your workspace
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Update the 'default' path alias that is used as the default source
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe for 'hg pull' and the default destination for 'hg push' (unless
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe there is a 'default-push' alias). This is also the path all
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Cadmium commands treat as your parent workspace.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe def append_new_parent(parent):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp = None
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe try:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp = repo.opener('hgrc', 'a', atomictemp=True)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if fp.tell() != 0:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.write('\n')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.write('[paths]\n'
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe 'default = %s\n\n' % parent)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.rename()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe finally:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if fp and not fp.closed:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.close()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe def update_parent(path, line, parent):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe line = line - 1 # The line number we're passed will be 1-based
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp = None
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe try:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp = open(path)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe data = fp.readlines()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe finally:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if fp and not fp.closed:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.close()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe #
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # line will be the last line of any continued block, go back
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # to the first removing the continuation as we go.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe #
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe while data[line][0].isspace():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe data.pop(line)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe line -= 1
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe assert data[line].startswith('default')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe data[line] = "default = %s\n" % parent
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if data[-1] != '\n':
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe data.append('\n')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe try:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp = util.atomictempfile(path, 'w', 0644)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.writelines(data)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.rename()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe finally:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if fp and not fp.closed:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe fp.close()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe from mercurial import config
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe parent = ui.expandpath(parent)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if not os.path.exists(repo.join('hgrc')):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe append_new_parent(parent)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe return
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe cfg = config.config()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe cfg.read(repo.join('hgrc'))
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe source = cfg.source('paths', 'default')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if not source:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe append_new_parent(parent)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe return
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe else:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe path, target = source.rsplit(':', 1)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if path != repo.join('hgrc'):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort("Cannot edit path specification not in repo hgrc\n"
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe "default path is from: %s" % source)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe update_parent(path, int(target), parent)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef backup_name(fullpath):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Create a backup directory name based on the specified path.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson In most cases this is the basename of the path specified, but
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson certain cases are handled specially to create meaningful names'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson special = ['usr/closed']
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson fullpath = fullpath.rstrip(os.path.sep).split(os.path.sep)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # If a path is 'special', we append the basename of the path to
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # the path element preceding the constant, special, part.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # Such that for instance:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # /foo/bar/onnv-fixes/usr/closed
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # has a backup name of:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # onnv-fixes-closed
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for elt in special:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson elt = elt.split(os.path.sep)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson pathpos = len(elt)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if fullpath[-pathpos:] == elt:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return "%s-%s" % (fullpath[-pathpos - 1], elt[-1])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return fullpath[-1]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_backup(ui, repo, if_newer=False):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''backup workspace changes and metadata
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Create a backup copy of changes made in this workspace as compared
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe to its parent workspace, as well as important metadata of this
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe workspace.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe NOTE: Only changes as compared to the parent workspace are backed
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe up. If you lose this workspace and its parent, you will not be
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe able to restore a backup into a clone of the grandparent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe workspace.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe By default, backups are stored in the cdm.backup/ directory in
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe your home directory. This is configurable using the cdm.backupdir
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe configuration variable, for example:
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe hg backup --config cdm.backupdir=/net/foo/backups
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe or place the following in an appropriate hgrc file::
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe [cdm]
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe backupdir = /net/foo/backups
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Backups have the same name as the workspace in which they were
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe taken, with '-closed' appended in the case of O/N's usr/closed.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson name = backup_name(repo.root)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bk = CdmBackup(ui, wslist[repo], name)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe wlock = repo.wlock()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe lock = repo.lock()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe try:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if if_newer and not bk.need_backup():
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe ui.status('backup is up-to-date\n')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe else:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe bk.backup()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe finally:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe lock.release()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe wlock.release()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef cdm_restore(ui, repo, backup, **opts):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''restore workspace from backup
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Restore this workspace from a backup (taken by 'hg backup').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe If the specified backup directory does not exist, it is assumed to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe be relative to the cadmium backup directory (~/cdm.backup/ by
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe default).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For example::
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe % hg restore on-rfe - Restore the latest backup of ~/cdm.backup/on-rfe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe % hg restore -g3 on-rfe - Restore the 3rd backup of ~/cdm.backup/on-rfe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe % hg restore /net/foo/backup/on-rfe - Restore from an explicit path
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not os.getcwd().startswith(repo.root):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson raise util.Abort('restore is not safe to run with -R')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe abort_if_dirty(wslist[repo])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if opts['generation']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson gen = int(opts['generation'])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson gen = None
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if os.path.exists(backup):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson backup = os.path.abspath(backup)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe wlock = repo.wlock()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe lock = repo.lock()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe try:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe bk = CdmBackup(ui, wslist[repo], backup)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe bk.restore(gen)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe finally:
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe lock.release()
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe wlock.release()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotaldef cdm_webrev(ui, repo, **opts):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''generate web-based code review and optionally upload it
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Generate a web-based code review using webrev(1) and optionally
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe upload it. All known arguments are passed through to webrev(1).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal webrev_args = ""
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal for key in opts.keys():
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe if opts[key]:
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe if type(opts[key]) == type(True):
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe webrev_args += '-' + key + ' '
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal else:
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe webrev_args += '-' + key + ' ' + opts[key] + ' '
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal retval = os.system('webrev ' + webrev_args)
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal if retval != 0:
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal return retval - 255
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal return 0
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowedef cdm_debugcdmal(ui, repo, *pats, **opts):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe '''dump the active list for the sake of debugging/testing'''
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write(wslist[repo].active(opts['parent']).as_text(pats))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowedef cdm_changed(ui, repo, *pats, **opts):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe '''mark a file as changed in the working copy
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Maintain a list of files checked for modification in the working
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe copy. If the list exists, most cadmium commands will only check
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe the working copy for changes to those files, rather than checking
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe the whole workspace (this does not apply to committed changes,
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe which are always seen).
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Since this list functions only as a hint as to where in the
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe working copy to look for changes, entries that have not actually
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe been modified (in the working copy, or in general) are not
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe problematic.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Note: If such a list exists, it must be kept up-to-date.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Renamed files can be added with reference only to their new name:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg mv foo bar
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed bar
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Without arguments, 'hg changed' will list all files recorded as
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe altered, such that, for instance:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg status $(hg changed)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg diff $(hg changed)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Become useful (generally faster than their unadorned counterparts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe To create an initially empty list:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed -i
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Until files are added to the list it is equivalent to saying
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe "Nothing has been changed"
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Update the list based on the current active list:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed -u
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe The old list is emptied, and replaced with paths from the
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe current active list.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Remove the list entirely:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed -d
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe '''
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe def modded_files(repo, parent):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe out = wslist[repo].findoutgoing(wslist[repo].parent(parent))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe outnodes = repo.changelog.nodesbetween(out)[0]
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe files = set()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for n in outnodes:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe files.update(repo.changectx(n).files())
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe files.update(wslist[repo].status().keys())
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe return files
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # specced_pats is convenient to treat as a boolean indicating
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # whether any file patterns or paths were specified.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe specced_pats = pats or opts['include'] or opts['exclude']
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if len(filter(None, [opts['delete'], opts['update'], opts['init'],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe specced_pats])) > 1:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe raise util.Abort("-d, -u, -i and patterns are mutually exclusive")
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl = WorkList(wslist[repo])
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if (not wl and specced_pats) or opts['init']:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.delete()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if yes_no(ui, "Create a list based on your changes thus far?", True):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe map(wl.add, modded_files(repo, opts.get('parent')))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if opts['delete']:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.delete()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe elif opts['update']:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.delete()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe map(wl.add, modded_files(repo, opts.get('parent')))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.write()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe elif opts['init']: # Any possible old list was deleted above
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.write()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe elif specced_pats:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe sources = []
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe match = wslist[repo].matcher(pats=pats, opts=opts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for abso in repo.walk(match):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if abso in repo.dirstate:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.add(abso)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # Store the source name of any copy. We use this so
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # both the add and delete of a rename can be entered
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # into the WorkList with only the destination name
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # explicitly being mentioned.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe #
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe fctx = wslist[repo].workingctx().filectx(abso)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe rn = fctx.renamed()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if rn:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe sources.append(rn[0])
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe else:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.warn("%s is not version controlled -- skipping\n" %
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe match.rel(abso))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if sources:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for fname, chng in wslist[repo].status(files=sources).iteritems():
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if chng == 'removed':
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.add(fname)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wl.write()
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe else:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for elt in sorted(wl.list()):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write("%s\n" % wslist[repo].filepath(elt))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsoncmdtable = {
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'apply': (cdm_apply, [('p', 'parent', '', 'parent workspace'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('r', 'remain', None, 'do not change directory')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg apply [-p PARENT] [-r] command...'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^backup|bu': (cdm_backup, [('t', 'if-newer', None,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'only backup if workspace files are newer')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg backup [-t]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'branchchk': (cdm_branchchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg branchchk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'bugs': (cdm_bugs, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg bugs [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'cddlchk': (cdm_cddlchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg cddlchk [-p PARENT]'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'changed': (cdm_changed, [('d', 'delete', None, 'delete the file list'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('u', 'update', None, 'mark all changed files'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('i', 'init', None, 'create an empty file list'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('p', 'parent', '', 'parent workspace'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('I', 'include', [],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'include names matching the given patterns'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('X', 'exclude', [],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'exclude names matching the given patterns')],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed -d\n'
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed -u\n'
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed -i\n'
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed [-I PATTERN...] [-X PATTERN...] [FILE...]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'comchk': (cdm_comchk, [('p', 'parent', '', 'parent workspace'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ('N', 'nocheck', None,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'do not compare comments with databases')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg comchk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'comments': (cdm_comments, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg comments [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'copyright': (cdm_copyright, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg copyright [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'cstyle': (cdm_cstyle, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg cstyle [-p PARENT]'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'debugcdmal': (cdm_debugcdmal, [('p', 'parent', '', 'parent workspace')],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg debugcdmal [-p PARENT] [FILE...]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'eval': (cdm_eval, [('p', 'parent', '', 'parent workspace'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('r', 'remain', None, 'do not change directory')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg eval [-p PARENT] [-r] command...'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hdrchk': (cdm_hdrchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg hdrchk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'jstyle': (cdm_jstyle, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg jstyle [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'keywords': (cdm_keywords, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg keywords [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^list|active': (cdm_list, [('p', 'parent', '', 'parent workspace'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ('a', 'added', None, 'show added files'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('m', 'modified', None, 'show modified files'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('r', 'removed', None, 'show removed files')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg list [-amrRu] [-p PARENT]'),
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore 'manlint': (cdm_manlintchk, [('p', 'parent', '', 'parent workspace')],
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore 'hg manlint [-p PARENT]'),
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami 'mapfilechk': (cdm_mapfilechk, [('p', 'parent', '', 'parent workspace')],
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami 'hg mapfilechk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^nits': (cdm_nits, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg nits [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^pbchk': (cdm_pbchk, [('p', 'parent', '', 'parent workspace'),
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe ('N', 'nocheck', None, 'skip database checks')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg pbchk [-N] [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'permchk': (cdm_permchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg permchk [-p PARENT]'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson '^pdiffs': (cdm_pdiffs, [('p', 'parent', '', 'parent workspace'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('a', 'text', None, 'treat all files as text'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('g', 'git', None, 'use extended git diff format'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('w', 'ignore-all-space', None,
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'ignore white space when comparing lines'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('b', 'ignore-space-change', None,
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'ignore changes in the amount of white space'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('B', 'ignore-blank-lines', None,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe 'ignore changes whose lines are all blank'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('U', 'unified', 3,
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'number of lines of context to show'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('I', 'include', [],
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'include names matching the given patterns'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('X', 'exclude', [],
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'exclude names matching the given patterns')],
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'hg pdiffs [OPTION...] [-p PARENT] [FILE...]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^recommit|reci': (cdm_recommit, [('p', 'parent', '', 'parent workspace'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ('m', 'message', '',
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'use <text> as commit message'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ('l', 'logfile', '',
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'read commit message from file'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ('u', 'user', '',
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'record user as committer')],
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe 'hg recommit [-m TEXT] [-l FILE] [-u USER] [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'renamed': (cdm_renamed, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg renamed [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'reparent': (cdm_reparent, [], 'hg reparent PARENT'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^restore': (cdm_restore, [('g', 'generation', '', 'generation number')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg restore [-g GENERATION] BACKUP'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'tagchk': (cdm_tagchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg tagchk [-p PARENT]'),
25cc4e45d2ae4f199cec8b3a58f01500f2db7815Vladimir Kotal 'webrev': (cdm_webrev, [('C', 'C', '', 'ITS priority file'),
25cc4e45d2ae4f199cec8b3a58f01500f2db7815Vladimir Kotal ('D', 'D', '', 'delete remote webrev'),
25cc4e45d2ae4f199cec8b3a58f01500f2db7815Vladimir Kotal ('I', 'I', '', 'ITS configuration file'),
ba44d8a2c0715f679ac0ccf227c557994cdb94a7Vladimir Kotal ('i', 'i', '', 'include file'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('N', 'N', None, 'suppress comments'),
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal ('n', 'n', None, 'do not generate webrev'),
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe ('O', 'O', None, 'OpenSolaris mode'),
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal ('o', 'o', '', 'output directory'),
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal ('p', 'p', '', 'use specified parent'),
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal ('t', 't', '', 'upload target'),
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe ('U', 'U', None, 'upload the webrev'),
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal ('w', 'w', '', 'use wx active file')],
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal 'hg webrev [WEBREV_OPTIONS]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson}