Merge with BOS
authormpm@selenic.com
Thu, 22 Sep 2005 09:39:05 -0700
changeset 1307 3b717f27ffea
parent 1286 4f08da74cae8 (current diff)
parent 1306 c9fa33088bd1 (diff)
child 1312 c9cf171f30dd
Merge with BOS
mercurial/commands.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/win32/ReadMe.html	Thu Sep 22 09:39:05 2005 -0700
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>Mercurial for Windows</title>
+  </head>
+
+  <body>
+    <h1>Mercurial version 0.7 for Windows</h1>
+
+    <p>Welcome to Mercurial for Windows!</p>
+
+    <p>Mercurial is a command-line application.  You must run it from
+      the Windows command prompt (or if you're hard core, a <a
+      href="http://www.mingw.org/">MinGW</a> shell).</p>
+
+    <p>For documentation, please visit the <a
+	href="http://www.selenic.com/mercurial">Mercurial web
+	site</a>.</p>
+
+    <p>By default, Mercurial installs to <tt>C:\Mercurial</tt>.  The
+      Mercurial command is called <tt>hg.exe</tt>.  To run this
+      command, the install directory must be in your search path.</p>
+
+    <h2>Setting your search path temporarily</h2>
+
+    <p>To set your search path temporarily, type the following into a
+      command prompt window:</p>
+
+    <pre>
+set PATH=C:\Mercurial;%PATH%
+</pre>
+
+    <h2>Setting your search path permanently</h2>
+
+    <p>To set your search path permanently, perform the following
+      steps.  These instructions are for Windows NT, 2000 and XP.</p>
+
+    <ol>
+      <li>Open the Control Panel.  Under Windows XP, select the
+	"Classic View".</li>
+
+      <li>Double-click on the "System" control panel.</li>
+
+      <li>Click on the "Advanced" tab.</li>
+
+      <li>Click on "Environment Variables".  You'll find this near the
+	bottom of the window.</li>
+
+      <li>Under "System variables", you will see "Path".  Double-click
+	it.</li>
+
+      <li>Edit "Variable value".  Each path element is separated by a
+	semicolon (";") character.  Append a semicolon to the end of the
+	list, followed by the path where you installed Mercurial
+	(e.g. <tt>C:\Mercurial</tt>).</li>
+
+      <li>Click on the various "OK" buttons until you've completely
+	exited from the System control panel.</li>
+
+      <li>Log out and log back in, or restart your system.</li>
+
+      <li>The next time you run the Windows command prompt, you will be
+	able to run the <tt>hg</tt> command without any special
+	help.</li>
+    </ol>
+
+    <h1>Testing Mercurial after you've installed it</h1>
+
+    <p>The easiest way to check that Mercurial is installed properly is to
+      just type the following at the command prompt:</p>
+
+    <pre>
+hg
+</pre>
+
+    <p>This command should print a useful help message.  If it does,
+      other Mercurial commands should work fine for you.</p>
+
+    <h1>Reporting problems</h1>
+
+    <p>Before you report any problems, please consult the <a
+	href="http://www.selenic.com/mercurial">Mercurial web site</a> and
+      see if your question is already in our list of <a
+	href="http://www.selenic.com/mercurial/wiki/index.cgi/FAQ">Frequently
+	Answered Questions</a> (the "FAQ").
+
+    <p>If you cannot find an answer to your question, please feel
+      free to send mail to the Mercurial mailing list, at <a
+	href="mailto:mercurial@selenic.com">mercurial@selenic.com</a>.
+      <b>Remember</b>, the more useful information you include in your
+      report, the easier it will be for us to help you!</p>
+
+    <p>If you are IRC-savvy, that's usually the fastest way to get
+      help.  Go to <tt>#mercurial</tt> on
+      <tt>irc.freenode.net</tt>.</p>
+
+    <h1>Author and copyright information</h1>
+
+    <p>Mercurial was written by <a href="http://www.selenic.com">Matt
+	Mackall</a>, and is maintained by Matt and a team of
+	volunteers.</p>
+
+    <p>The Windows installer was written by <a
+	href="http://www.serpentine.com/blog">Bryan
+	O'Sullivan</a>.</p>
+
+    <p>Mercurial is Copyright 2005 Matt Mackall and others.  See the
+      <tt>Contributors.txt</tt> file for a list of contributors.</p>
+
+    <p>Mercurial is free software; you can redistribute it and/or
+      modify it under the terms of the <a
+	href="http://www.gnu.org/copyleft/gpl.html">GNU General Public
+	License</a> as published by the Free Software Foundation; either
+      version 2 of the License, or (at your option) any later
+      version.</p>
+
+    <p>Mercurial is distributed in the hope that it will be useful,
+      but <b>without any warranty</b>; without even the implied
+      warranty of <b>merchantability</b> or <b>fitness for a
+      particular purpose</b>.  See the GNU General Public License for
+      more details.</p>
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/win32/mercurial.ini	Thu Sep 22 09:39:05 2005 -0700
@@ -0,0 +1,36 @@
+; System-wide Mercurial config file.  To override these settings on a
+; per-user basis, please edit the following file instead, where
+; USERNAME is your Windows user name:
+;   C:\Documents and Settings\USERNAME\Mercurial.ini
+
+; By default, we try to encode and decode all files that do not
+; contain ASCII NUL characters.  What this means is that we try to set
+; line endings to Windows style on update, and to Unix style on
+; commit.  This lets us cooperate with Linux and Unix users, so
+; everybody sees files with their native line endings.
+
+[extensions]
+; The win32text extension is available and installed by default.  It
+; provides built-in Python hooks to perform line ending conversions.
+; This is normally much faster than running an external program.
+hgext.win32text =
+
+
+[encode]
+; Encode files that don't contain NUL characters.
+** = cleverencode:
+
+; Alternatively, you can explicitly specify each file extension that
+; you want encoded (any you omit will be left untouched), like this:
+
+; *.txt = dumbencode:
+
+
+[decode]
+; Decode files that don't contain NUL characters.
+** = cleverdecode:
+
+; Alternatively, you can explicitly specify each file extension that
+; you want decoded (any you omit will be left untouched), like this:
+
+; **.txt = dumbdecode:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/win32/mercurial.iss	Thu Sep 22 09:39:05 2005 -0700
@@ -0,0 +1,58 @@
+; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+AppCopyright=Copyright 2005 Matt Mackall and others
+AppName=Mercurial
+AppVerName=Mercurial version 0.7
+InfoAfterFile=contrib/win32/postinstall.txt
+LicenseFile=COPYING
+ShowLanguageDialog=yes
+AppPublisher=Matt Mackall and others
+AppPublisherURL=http://www.selenic.com/mercurial
+AppSupportURL=http://www.selenic.com/mercurial
+AppUpdatesURL=http://www.selenic.com/mercurial
+AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}
+AppContact=mercurial@selenic.com
+OutputBaseFilename=Mercurial-0.7
+DefaultDirName={sd}\Mercurial
+SourceDir=C:\hg\hg-release
+VersionInfoVersion=0.7
+VersionInfoDescription=Mercurial distributed SCM
+VersionInfoCopyright=Copyright 2005 Matt Mackall and others
+VersionInfoCompany=Matt Mackall and others
+InternalCompressLevel=max
+SolidCompression=true
+SetupIconFile=contrib\favicon.ico
+AllowNoIcons=true
+DefaultGroupName=Mercurial
+
+[Files]
+Source: templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs
+Source: contrib\mercurial.el; DestDir: {app}/Contrib
+Source: contrib\patchbomb; DestDir: {app}/Contrib
+Source: dist\w9xpopen.exe; DestDir: {app}
+Source: dist\hg.exe; DestDir: {app}
+Source: dist\msvcr71.dll; DestDir: {sys}; Flags: sharedfile uninsnosharedfileprompt
+Source: dist\library.zip; DestDir: {app}
+Source: doc\*.txt; DestDir: {app}\Docs
+Source: dist\mfc71.dll; DestDir: {sys}; Flags: sharedfile uninsnosharedfileprompt
+Source: COPYING; DestDir: {app}; DestName: Copying.txt
+Source: comparison.txt; DestDir: {app}\Docs; DestName: Comparison.txt
+Source: notes.txt; DestDir: {app}\Docs; DestName: DesignNotes.txt
+Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
+Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
+Source: ..\..\msys\1.0\bin\patch.exe; DestDir: {app}
+Source: contrib\win32\mercurial.ini; DestDir: {app}; DestName: Mercurial.ini; Flags: confirmoverwrite
+Source: contrib\win32\postinstall.txt; DestDir: {app}; DestName: ReleaseNotes.txt
+
+[INI]
+Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: http://www.selenic.com/mercurial/
+
+[UninstallDelete]
+Type: files; Name: {app}\Mercurial.url
+
+[Icons]
+Name: {group}\Uninstall Mercurial; Filename: {uninstallexe}
+Name: {group}\Mercurial Command Reference; Filename: {app}\Docs\hg.1.txt
+Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/win32/postinstall.txt	Thu Sep 22 09:39:05 2005 -0700
@@ -0,0 +1,38 @@
+Welcome to Mercurial for Windows!
+---------------------------------
+
+For configuration and usage directions, please read the ReadMe.html
+file that comes with this package.
+
+
+Release Notes
+-------------
+
+2005-09-21  v0.7 with modifications
+
+* New INI files have been added to control Mercurial's behaviour:
+
+    System-wide -  C:\Mercurial\Mercurial.ini
+    Per-user    -  C:\Documents and Settings\USERNAME\Mercurial.ini
+
+  A default version of the system-wide INI file is installed with
+  Mercurial.  No per-user INI file is installed, but it will be
+  honoured if you create one.
+
+* Windows line endings are now handled automatically and correctly by
+  the update and commit commands.  See the INI file for how to
+  customise this behaviour.
+
+* NOTE: Much of the rest of the Mercurial code does not handle Windows
+  line endings properly.  Accordingly, the output of the diff command,
+  for example, will appear huge until I fix this.
+
+* Packaged text files now have correct Windows line endings.
+
+
+2005-09-21  v0.7 with modifications
+
+* This is the first standalone release of Mercurial for Windows.
+
+* I believe it to be mostly functional, with one exception: there is
+  no support yet for DOS <-> Unix line ending conversion.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/win32/win32-build.txt	Thu Sep 22 09:39:05 2005 -0700
@@ -0,0 +1,43 @@
+The standalone Windows installer for Mercurial is built in a somewhat
+jury-rigged fashion.
+
+It has the following prerequisites, at least as I build it:
+
+  Python for Windows
+      http://www.python.org/ftp/python/2.4.1/python-2.4.1.msi
+
+  MinGW
+      http://www.mingw.org/
+
+  Python for Windows Extensions
+      http://sourceforge.net/projects/pywin32/
+
+  mfc71.dll (just download, don't install)
+      http://starship.python.net/crew/mhammond/win32/
+
+  The py2exe distutils extension
+      http://sourceforge.net/projects/py2exe/
+
+  Inno Setup
+      http://www.jrsoftware.org/isinfo.php
+
+  ISTool
+      http://www.istool.org/default.aspx/
+
+And, of course, Mercurial itself.
+
+Once you have all this installed and built, clone a copy of the
+Mercurial repository you want to package, and name the repo
+C:\hg\hg-release.
+
+In a shell, build a standalone copy of the hg.exe program:
+
+  python setup.py build -c mingw32 py2exe -b 1
+
+Copy mfc71.dll into the dist directory that just got created.
+
+Run ISTool, and open the C:\hg\hg-release\contrib\win32\mercurial.iss
+file.
+
+In ISTool, type Ctrl-F9 to compile the installer file.  The actual
+installer will be in the C:\hg\hg-release\Output directory.
--- a/doc/hgrc.5.txt	Thu Sep 22 09:22:25 2005 -0700
+++ b/doc/hgrc.5.txt	Thu Sep 22 09:39:05 2005 -0700
@@ -15,18 +15,22 @@
 FILES
 -----
 
-Mercurial reads configuration data from three files:
+Mercurial reads configuration data from up to three files, if they
+exist.  The names of these files depend on the system on which
+Mercurial is installed.
 
-/etc/mercurial/hgrc::
+(Unix)    /etc/mercurial/hgrc::
+(Windows) C:\Mercurial\Mercurial.ini::
     Options in this global configuration file apply to all Mercurial
     commands executed by any user in any directory.
 
-$HOME/.hgrc::
+(Unix)    $HOME/.hgrc::
+(Windows) C:\Documents and Settings\USERNAME\Mercurial.ini
     Per-user configuration options that apply to all Mercurial commands,
     no matter from which directory they are run.  Values in this file
     override global settings.
 
-<repo>/.hg/hgrc::
+(Unix, Windows) <repo>/.hg/hgrc::
     Per-repository configuration options that only apply in a
     particular repository.  This file is not version-controlled, and
     will not get transferred during a "clone" operation.  Values in
@@ -67,20 +71,53 @@
   localization/canonicalization of files.
 
   Filters consist of a filter pattern followed by a filter command.
-  The command must accept data on stdin and return the transformed
-  data on stdout.
+  Filter patterns are globs by default, rooted at the repository
+  root.  For example, to match any file ending in ".txt" in the root
+  directory only, use the pattern "*.txt".  To match any file ending
+  in ".c" anywhere in the repository, use the pattern "**.c".
 
-  Example:
+  The filter command can start with a specifier, either "pipe:" or
+  "tempfile:".  If no specifier is given, "pipe:" is used by default.
+
+  A "pipe:" command must accept data on stdin and return the
+  transformed data on stdout.
+
+  Pipe example:
 
     [encode]
     # uncompress gzip files on checkin to improve delta compression
     # note: not necessarily a good idea, just an example
-    *.gz = gunzip
+    *.gz = pipe: gunzip
 
     [decode]
-    # recompress gzip files when writing them to the working dir
+    # recompress gzip files when writing them to the working dir (we
+    # can safely omit "pipe:", because it's the default)
     *.gz = gzip
 
+  A "tempfile:" command is a template.  The string INFILE is replaced
+  with the name of a temporary file that contains the data to be
+  filtered by the command.  The string OUTFILE is replaced with the
+  name of an empty temporary file, where the filtered data must be
+  written by the command.
+
+  NOTE: the tempfile mechanism is recommended for Windows systems,
+  where the standard shell I/O redirection operators often have
+  strange effects.  In particular, if you are doing line ending
+  conversion on Windows using the popular dos2unix and unix2dos
+  programs, you *must* use the tempfile mechanism, as using pipes will
+  corrupt the contents of your files.
+
+  Tempfile example:
+
+    [encode]
+    # convert files to unix line ending conventions on checkin
+    **.txt = tempfile: dos2unix -n INFILE OUTFILE
+
+    [decode]
+    # convert files to windows line ending conventions when writing
+    # them to the working dir
+    **.txt = tempfile: unix2dos -n INFILE OUTFILE
+
 hooks::
   Commands that get automatically executed by various actions such as
   starting or finishing a commit.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext/win32text.py	Thu Sep 22 09:39:05 2005 -0700
@@ -0,0 +1,28 @@
+import mercurial.util
+
+def dumbdecode(s, cmd):
+    return s.replace('\n', '\r\n')
+
+def dumbencode(s, cmd):
+    return s.replace('\r\n', '\n')
+
+def clevertest(s, cmd):
+    if '\0' in s: return False
+    return True
+
+def cleverdecode(s, cmd):
+    if clevertest(s, cmd):
+        return dumbdecode(s, cmd)
+    return s
+
+def cleverencode(s, cmd):
+    if clevertest(s, cmd):
+        return dumbencode(s, cmd)
+    return s
+
+mercurial.util.filtertable.update({
+    'dumbdecode:': dumbdecode,
+    'dumbencode:': dumbencode,
+    'cleverdecode:': cleverdecode,
+    'cleverencode:': cleverencode,
+    })
--- a/mercurial/commands.py	Thu Sep 22 09:22:25 2005 -0700
+++ b/mercurial/commands.py	Thu Sep 22 09:39:05 2005 -0700
@@ -2051,10 +2051,11 @@
             mod = importh(x[0])
         external.append(mod)
     for x in external:
-        for t in x.cmdtable:
+        cmdtable = getattr(x, 'cmdtable', {})
+        for t in cmdtable:
             if t in table:
-                u.warn("module %s override %s\n" % (x.__name__, t))
-        table.update(x.cmdtable)
+                u.warn("module %s overrides %s\n" % (x.__name__, t))
+        table.update(cmdtable)
 
     try:
         cmd, func, args, options, cmdoptions = parse(args)
@@ -2114,7 +2115,7 @@
                 path = options["repository"] or ""
                 repo = hg.repository(ui=u, path=path)
                 for x in external:
-                    x.reposetup(u, repo)
+                    if hasattr(x, 'reposetup'): x.reposetup(u, repo)
                 d = lambda: func(u, repo, *args, **cmdoptions)
             else:
                 d = lambda: func(u, *args, **cmdoptions)
--- a/mercurial/ui.py	Thu Sep 22 09:22:25 2005 -0700
+++ b/mercurial/ui.py	Thu Sep 22 09:39:05 2005 -0700
@@ -14,8 +14,7 @@
                  interactive=True):
         self.overlay = {}
         self.cdata = ConfigParser.SafeConfigParser()
-        self.cdata.read([os.path.normpath(hgrc) for hgrc in
-                         "/etc/mercurial/hgrc", os.path.expanduser("~/.hgrc")])
+        self.cdata.read(util.rcpath)
 
         self.quiet = self.configbool("ui", "quiet")
         self.verbose = self.configbool("ui", "verbose")
--- a/mercurial/util.py	Thu Sep 22 09:22:25 2005 -0700
+++ b/mercurial/util.py	Thu Sep 22 09:39:05 2005 -0700
@@ -12,10 +12,10 @@
 
 import os, errno
 from demandload import *
-demandload(globals(), "re cStringIO shutil popen2 threading")
+demandload(globals(), "re cStringIO shutil popen2 tempfile threading")
 
-def filter(s, cmd):
-    "filter a string through a command that transforms its input to its output"
+def pipefilter(s, cmd):
+    '''filter string S through command CMD, returning its output'''
     (pout, pin) = popen2.popen2(cmd, -1, 'b')
     def writer():
         pin.write(s)
@@ -30,6 +30,45 @@
     w.join()
     return f
 
+def tempfilter(s, cmd):
+    '''filter string S through a pair of temporary files with CMD.
+    CMD is used as a template to create the real command to be run,
+    with the strings INFILE and OUTFILE replaced by the real names of
+    the temporary files generated.'''
+    inname, outname = None, None
+    try:
+        infd, inname = tempfile.mkstemp(prefix='hgfin')
+        fp = os.fdopen(infd, 'wb')
+        fp.write(s)
+        fp.close()
+        outfd, outname = tempfile.mkstemp(prefix='hgfout')
+        os.close(outfd)
+        cmd = cmd.replace('INFILE', inname)
+        cmd = cmd.replace('OUTFILE', outname)
+        code = os.system(cmd)
+        if code: raise Abort("command '%s' failed: %s" %
+                             (cmd, explain_exit(code)))
+        return open(outname, 'rb').read()
+    finally:
+        try:
+            if inname: os.unlink(inname)
+        except: pass
+        try:
+            if outname: os.unlink(outname)
+        except: pass
+
+filtertable = {
+    'tempfile:': tempfilter,
+    'pipe:': pipefilter,
+    }
+
+def filter(s, cmd):
+    "filter a string through a command that transforms its input to its output"
+    for name, fn in filtertable.iteritems():
+        if cmd.startswith(name):
+            return fn(s, cmd[len(name):].lstrip())
+    return pipefilter(s, cmd)
+
 def patch(strip, patchname, ui):
     """apply the patch <patchname> to the working directory.
     a list of patched files is returned"""
@@ -43,9 +82,9 @@
             files.setdefault(pf, 1)
     code = fp.close()
     if code:
-        raise Abort("patch command failed: exit status %s " % code)
+        raise Abort("patch command failed: %s" % explain_exit(code))
     return files.keys()
-    
+
 def binary(s):
     """return true if a string is binary data using diff's heuristic"""
     if s and '\0' in s[:4096]:
@@ -331,6 +370,9 @@
 if os.name == 'nt':
     nulldev = 'NUL:'
 
+    rcpath = (r'c:\mercurial\mercurial.ini',
+              os.path.join(os.path.expanduser('~'), 'mercurial.ini'))
+
     def parse_patch_output(output_line):
         """parses the output produced by patch and returns the file name"""
         pf = output_line[14:]
@@ -383,6 +425,9 @@
 else:
     nulldev = '/dev/null'
 
+    rcpath = map(os.path.normpath,
+                 ('/etc/mercurial/hgrc', os.path.expanduser('~/.hgrc')))
+
     def parse_patch_output(output_line):
         """parses the output produced by patch and returns the file name"""
         return output_line[14:]
--- a/setup.py	Thu Sep 22 09:22:25 2005 -0700
+++ b/setup.py	Thu Sep 22 09:39:05 2005 -0700
@@ -13,13 +13,13 @@
 
 # py2exe needs to be installed to work
 try:
-    import py2exe 
+    import py2exe
 
     # Due to the use of demandload py2exe is not finding the modules.
-    # packagescan.getmodules creates a list of modules included in 
+    # packagescan.getmodules creates a list of modules included in
     # the mercurial package plus depdent modules.
-    import mercurial.packagescan 
-    from py2exe.build_exe import py2exe as build_exe 
+    import mercurial.packagescan
+    from py2exe.build_exe import py2exe as build_exe
 
     class py2exe_for_demandload(build_exe):
         """ overwrites the py2exe command class for getting the build
@@ -34,7 +34,10 @@
             # Sets the 'includes' option with the list of needed modules
             if not self.includes:
                 self.includes = []
-            self.includes += mercurial.packagescan.getmodules(self.build_lib,'mercurial')
+            self.includes += mercurial.packagescan.getmodules(self.build_lib,
+                                                              'mercurial')
+            self.includes += mercurial.packagescan.getmodules(self.build_lib,
+                                                              'hgext')
             build_exe.finalize_options(self)
 except ImportError:
     py2exe_for_demandload = None
@@ -61,7 +64,7 @@
           url='http://selenic.com/mercurial',
           description='scalable distributed SCM',
           license='GNU GPL',
-          packages=['mercurial'],
+          packages=['mercurial', 'hgext'],
           ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
                        Extension('mercurial.bdiff', ['mercurial/bdiff.c'])],
           data_files=[('mercurial/templates',