merge with i18n stable
authorMatt Mackall <mpm@selenic.com>
Fri, 31 Jul 2015 10:26:57 -0500
branchstable
changeset 25886 f6e159237260
parent 25884 b810b59eca62 (diff)
parent 25885 88546cc32d8f (current diff)
child 25887 21aa1c313b05
merge with i18n
--- a/hgext/convert/__init__.py	Fri Jul 31 18:39:48 2015 +0900
+++ b/hgext/convert/__init__.py	Fri Jul 31 10:26:57 2015 -0500
@@ -192,6 +192,9 @@
         (forces target IDs to change). It takes a boolean argument and
         defaults to False.
 
+    :convert.hg.startrev: specify the initial Mercurial revision.
+        The default is 0.
+
     :convert.hg.revs: revset specifying the source revisions to convert.
 
     CVS Source
@@ -323,8 +326,11 @@
     usually should specify a target directory, because otherwise the
     target may be named ``...-hg``.
 
-    It is possible to limit the amount of source history to be
-    converted by specifying an initial Perforce revision:
+    The following options can be set with ``--config``:
+
+    :convert.p4.encoding: specify the encoding to use when decoding standard
+        output of the Perforce command line tool. The default is default system
+        encoding.
 
     :convert.p4.startrev: specify initial Perforce revision (a
         Perforce changelist number).
--- a/hgext/convert/p4.py	Fri Jul 31 18:39:48 2015 +0900
+++ b/hgext/convert/p4.py	Fri Jul 31 10:26:57 2015 -0500
@@ -39,6 +39,9 @@
 
 class p4_source(converter_source):
     def __init__(self, ui, path, revs=None):
+        # avoid import cycle
+        import convcmd
+
         super(p4_source, self).__init__(ui, path, revs=revs)
 
         if "/" in path and not path.startswith('//'):
@@ -54,7 +57,8 @@
         self.tags = {}
         self.lastbranch = {}
         self.parent = {}
-        self.encoding = "latin_1"
+        self.encoding = self.ui.config('convert', 'p4.encoding',
+                                       default=convcmd.orig_encoding)
         self.depotname = {}           # mapping from local name to depot name
         self.localname = {} # mapping from depot name to local name
         self.re_type = re.compile(
@@ -216,7 +220,7 @@
             stdout = util.popen(cmd, mode='rb')
 
             mode = None
-            contents = ""
+            contents = []
             keywords = None
 
             for d in loaditer(stdout):
@@ -252,7 +256,7 @@
                             keywords = self.re_keywords
 
                 elif code == "text" or code == "binary":
-                    contents += data
+                    contents.append(data)
 
                 lasterror = None
 
@@ -262,6 +266,8 @@
         if mode is None:
             return None, None
 
+        contents = ''.join(contents)
+
         if keywords:
             contents = keywords.sub("$\\1$", contents)
         if mode == "l" and contents.endswith("\n"):
--- a/hgext/transplant.py	Fri Jul 31 18:39:48 2015 +0900
+++ b/hgext/transplant.py	Fri Jul 31 10:26:57 2015 -0500
@@ -125,9 +125,10 @@
         diffopts = patch.difffeatureopts(self.ui, opts)
         diffopts.git = True
 
-        lock = wlock = tr = None
+        lock = wlock = tr = dsguard = None
         try:
             wlock = repo.wlock()
+            dsguard = cmdutil.dirstateguard(repo, 'transplant')
             lock = repo.lock()
             tr = repo.transaction('transplant')
             for rev in revs:
@@ -200,6 +201,7 @@
                             # Do not rollback, it is up to the user to
                             # fix the merge or cancel everything
                             tr.close()
+                            dsguard.close()
                             raise
                         if n and domerge:
                             self.ui.status(_('%s merged at %s\n') % (revstr,
@@ -212,6 +214,7 @@
                         if patchfile:
                             os.unlink(patchfile)
             tr.close()
+            dsguard.close()
             if pulls:
                 exchange.pull(repo, source.peer(), heads=pulls)
                 merge.update(repo, pulls[-1], False, False, None)
@@ -220,7 +223,10 @@
             self.transplants.write()
             if tr:
                 tr.release()
-            lock.release()
+            if lock:
+                lock.release()
+            if dsguard:
+                dsguard.release()
             wlock.release()
 
     def filter(self, filter, node, changelog, patchfile):
--- a/mercurial/help.py	Fri Jul 31 18:39:48 2015 +0900
+++ b/mercurial/help.py	Fri Jul 31 10:26:57 2015 -0500
@@ -166,6 +166,8 @@
     (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
      loaddoc('hgignore')),
     (["phases"], _("Working with Phases"), loaddoc('phases')),
+    (['scripting'], _('Using Mercurial from scripts and automation'),
+     loaddoc('scripting')),
 ])
 
 # Map topics to lists of callable taking the current topic help and
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/help/scripting.txt	Fri Jul 31 10:26:57 2015 -0500
@@ -0,0 +1,174 @@
+It is common for machines (as opposed to humans) to consume Mercurial.
+This help topic describes some of the considerations for interfacing
+machines with Mercurial.
+
+Choosing an Interface
+=====================
+
+Machines have a choice of several methods to interface with Mercurial.
+These include:
+
+- Executing the ``hg`` process
+- Querying a HTTP server
+- Calling out to a command server
+
+Executing ``hg`` processes is very similar to how humans interact with
+Mercurial in the shell. It should already be familar to you.
+
+:hg:`serve` can be used to start a server. By default, this will start
+a "hgweb" HTTP server. This HTTP server has support for machine-readable
+output, such as JSON. For more, see :hg:`help hgweb`.
+
+:hg:`serve` can also start a "command server." Clients can connect
+to this server and issue Mercurial commands over a special protocol.
+For more details on the command server, including links to client
+libraries, see https://mercurial.selenic.com/wiki/CommandServer.
+
+:hg:`serve` based interfaces (the hgweb and command servers) have the
+advantage over simple ``hg`` process invocations in that they are
+likely more efficient. This is because there is significant overhead
+to spawn new Python processes.
+
+.. tip::
+
+   If you need to invoke several ``hg`` processes in short order and/or
+   performance is important to you, use of a server-based interface
+   is highly recommended.
+
+Environment Variables
+=====================
+
+As documented in :hg:`help environment`, various environment variables
+influence the operation of Mercurial. The following are particularly
+relevant for machines consuming Mercurial:
+
+HGPLAIN
+    If not set, Mercurial's output could be influenced by configuration
+    settings that impact its encoding, verbose mode, localization, etc.
+
+    It is highly recommended for machines to set this variable when
+    invoking ``hg`` processes.
+
+HGENCODING
+   If not set, the locale used by Mercurial will be detected from the
+   environment. If the determined locale does not support display of
+   certain characters, Mercurial may render these character sequences
+   incorrectly (often by using "?" as a placeholder for invalid
+   characters in the current locale).
+
+   Explcitly setting this environment variable is a good practice to
+   guarantee consistent results. "utf-8" is a good choice on UNIX-like
+   environments.
+
+HGRCPATH
+    If not set, Mercurial will inherit config options from config files
+    using the process described in :hg:`help config`. This includes
+    inheriting user or system-wide config files.
+
+    When utmost control over the Mercurial configuration is desired, the
+    value of ``HGRCPATH`` can be set to an explicit file with known good
+    configs. In rare cases, the value can be set to an empty file or the
+    null device (often ``/dev/null``) to bypass loading of any user or
+    system config files. Note that these approaches can have unintended
+    consequences, as the user and system config files often define things
+    like the username and extensions that may be required to interface
+    with a repository.
+
+Consuming Command Output
+========================
+
+It is common for machines to need to parse the output of Mercurial
+commands for relevant data. This section describes the various
+techniques for doing so.
+
+Parsing Raw Command Output
+--------------------------
+
+Likely the simplest and most effective solution for consuming command
+output is to simply invoke ``hg`` commands as you would as a user and
+parse their output.
+
+The output of many commands can easily be parsed with tools like
+``grep``, ``sed``, and ``awk``.
+
+A potential downside with parsing command output is that the output
+of commands can change when Mercurial is upgraded. While Mercurial
+does generally strive for strong backwards compatibility, command
+output does occasionally change. Having tests for your automated
+interactions with ``hg`` commands is generally recommended, but is
+even more important when raw command output parsing is involved.
+
+Using Templates to Control Output
+---------------------------------
+
+Many ``hg`` commands support templatized output via the
+``-T/--template`` argument. For more, see :hg:`help templates`.
+
+Templates are useful for explicitly controlling output so that
+you get exactly the data you want formatted how you want it. For
+example, ``log -T {node}\n`` can be used to print a newline
+delimited list of changeset nodes instead of a human-tailored
+output containing authors, dates, descriptions, etc.
+
+.. tip::
+
+   If parsing raw command output is too complicated, consider
+   using templates to make your life easier.
+
+The ``-T/--template`` argument allows specifying pre-defined styles.
+Mercurial ships with the machine-readable styles ``json`` and ``xml``,
+which provide JSON and XML output, respectively. These are useful for
+producing output that is machine readable as-is.
+
+.. important::
+
+   The ``json`` and ``xml`` styles are considered experimental. While
+   they may be attractive to use for easily obtaining machine-readable
+   output, their behavior may change in subsequent versions.
+
+   These styles may also exhibit unexpected results when dealing with
+   certain encodings. Mercurial treats things like filenames as a
+   series of bytes and normalizing certain byte sequences to JSON
+   or XML with certain encoding settings can lead to surprises.
+
+Command Server Output
+---------------------
+
+If using the command server to interact with Mercurial, you are likely
+using an existing library/API that abstracts implementation details of
+the command server. If so, this interface layer may perform parsing for
+you, saving you the work of implementing it yourself.
+
+Output Verbosity
+----------------
+
+Commands often have varying output verbosity, even when machine
+readable styles are being used (e.g. ``-T json``). Adding
+``-v/--verbose`` and ``--debug`` to the command's arguments can
+increase the amount of data exposed by Mercurial.
+
+An alternate way to get the data you need is by explicitly specifying
+a template.
+
+Other Topics
+============
+
+revsets
+   Revisions sets is a functional query language for selecting a set
+   of revisions. Think of it as SQL for Mercurial repositories. Revsets
+   are useful for querying repositories for specific data.
+
+   See :hg:`help revsets` for more.
+
+share extension
+   The ``share`` extension provides functionality for sharing
+   repository data across several working copies. It can even
+   automatically "pool" storage for logically related repositories when
+   cloning.
+
+   Configuring the ``share`` extension can lead to significant resource
+   utilization reduction, particularly around disk space and the
+   network. This is especially true for continuous integration (CI)
+   environments.
+
+   See :hg:`help -e share` for more.
--- a/mercurial/localrepo.py	Fri Jul 31 18:39:48 2015 +0900
+++ b/mercurial/localrepo.py	Fri Jul 31 10:26:57 2015 -0500
@@ -968,6 +968,9 @@
                 _("abandoned transaction found"),
                 hint=_("run 'hg recover' to clean up transaction"))
 
+        # make journal.dirstate contain in-memory changes at this point
+        self.dirstate.write()
+
         idbase = "%.40f#%f" % (random.random(), time.time())
         txnid = 'TXN:' + util.sha1(idbase).hexdigest()
         self.hook('pretxnopen', throw=True, txnname=desc, txnid=txnid)
--- a/tests/test-backout.t	Fri Jul 31 18:39:48 2015 +0900
+++ b/tests/test-backout.t	Fri Jul 31 10:26:57 2015 -0500
@@ -130,6 +130,34 @@
   update: (current)
   phases: 4 draft
 
+Test that 'hg rollback' restores dirstate just before opening
+transaction: in-memory dirstate changes should be written into
+'.hg/journal.dirstate' as expected.
+
+  $ echo 'removed soon' > b
+  $ hg commit -A -d '4 0' -m 'prepare for subsequent removing'
+  adding b
+  $ echo 'newly added' > c
+  $ hg add c
+  $ hg remove b
+  $ hg commit -d '5 0' -m 'prepare for subsequent backout'
+  $ touch -t 200001010000 c
+  $ hg status -A
+  C c
+  $ hg debugstate --nodates
+  n 644         12 set                 c
+  $ hg backout -d '6 0' -m 'to be rollback-ed soon' -r .
+  adding b
+  removing c
+  changeset 6:4bfec048029d backs out changeset 5:fac0b729a654
+  $ hg rollback -q
+  $ hg status -A
+  A b
+  R c
+  $ hg debugstate --nodates
+  a   0         -1 unset               b
+  r   0          0 set                 c
+
 across branch
 
   $ cd ..
--- a/tests/test-convert.t	Fri Jul 31 18:39:48 2015 +0900
+++ b/tests/test-convert.t	Fri Jul 31 10:26:57 2015 -0500
@@ -143,6 +143,8 @@
                     store original revision ID in changeset (forces target IDs
                     to change). It takes a boolean argument and defaults to
                     False.
+      convert.hg.startrev
+                    specify the initial Mercurial revision. The default is 0.
       convert.hg.revs
                     revset specifying the source revisions to convert.
   
@@ -273,9 +275,12 @@
       that when a depot path is given you then usually should specify a target
       directory, because otherwise the target may be named "...-hg".
   
-      It is possible to limit the amount of source history to be converted by
-      specifying an initial Perforce revision:
+      The following options can be set with "--config":
   
+      convert.p4.encoding
+                    specify the encoding to use when decoding standard output of
+                    the Perforce command line tool. The default is default
+                    system encoding.
       convert.p4.startrev
                     specify initial Perforce revision (a Perforce changelist
                     number).
--- a/tests/test-globalopts.t	Fri Jul 31 18:39:48 2015 +0900
+++ b/tests/test-globalopts.t	Fri Jul 31 10:26:57 2015 -0500
@@ -355,6 +355,7 @@
    phases        Working with Phases
    revisions     Specifying Single Revisions
    revsets       Specifying Revision Sets
+   scripting     Using Mercurial from scripts and automation
    subrepos      Subrepositories
    templating    Template Usage
    urls          URL Paths
@@ -436,6 +437,7 @@
    phases        Working with Phases
    revisions     Specifying Single Revisions
    revsets       Specifying Revision Sets
+   scripting     Using Mercurial from scripts and automation
    subrepos      Subrepositories
    templating    Template Usage
    urls          URL Paths
--- a/tests/test-help.t	Fri Jul 31 18:39:48 2015 +0900
+++ b/tests/test-help.t	Fri Jul 31 10:26:57 2015 -0500
@@ -117,6 +117,7 @@
    phases        Working with Phases
    revisions     Specifying Single Revisions
    revsets       Specifying Revision Sets
+   scripting     Using Mercurial from scripts and automation
    subrepos      Subrepositories
    templating    Template Usage
    urls          URL Paths
@@ -192,6 +193,7 @@
    phases        Working with Phases
    revisions     Specifying Single Revisions
    revsets       Specifying Revision Sets
+   scripting     Using Mercurial from scripts and automation
    subrepos      Subrepositories
    templating    Template Usage
    urls          URL Paths
@@ -740,6 +742,7 @@
    phases        Working with Phases
    revisions     Specifying Single Revisions
    revsets       Specifying Revision Sets
+   scripting     Using Mercurial from scripts and automation
    subrepos      Subrepositories
    templating    Template Usage
    urls          URL Paths
@@ -1406,6 +1409,13 @@
   Specifying Revision Sets
   </td></tr>
   <tr><td>
+  <a href="/help/scripting">
+  scripting
+  </a>
+  </td><td>
+  Using Mercurial from scripts and automation
+  </td></tr>
+  <tr><td>
   <a href="/help/subrepos">
   subrepos
   </a>
--- a/tests/test-hgweb-json.t	Fri Jul 31 18:39:48 2015 +0900
+++ b/tests/test-hgweb-json.t	Fri Jul 31 10:26:57 2015 -0500
@@ -1086,6 +1086,10 @@
         "topic": "revsets"
       },
       {
+        "summary": "Using Mercurial from scripts and automation",
+        "topic": "scripting"
+      },
+      {
         "summary": "Subrepositories",
         "topic": "subrepos"
       },
--- a/tests/test-transplant.t	Fri Jul 31 18:39:48 2015 +0900
+++ b/tests/test-transplant.t	Fri Jul 31 10:26:57 2015 -0500
@@ -867,6 +867,7 @@
   > [hooks]
   > fakedirstatewritetime = !
   > fakepatchtime = !
+  > [extensions]
   > abort = !
   > EOF
 
@@ -877,4 +878,41 @@
   $ hg status -A r1
   M r1
 
+Test that rollback by unexpected failure after transplanting the first
+revision restores dirstate correctly.
+
+  $ hg rollback -q
+  $ rm -f abort
+  $ hg update -q -C d11e3596cc1a
+  $ hg parents -T "{node|short}\n"
+  d11e3596cc1a
+  $ hg status -A
+  C r1
+  C r2
+
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > # emulate failure at transplanting the 2nd revision
+  > pretxncommit.abort = test ! -f abort
+  > EOF
+  $ hg transplant "22c515968f13::"
+  applying 22c515968f13
+  22c515968f13 transplanted to * (glob)
+  applying e38700ba9dd3
+  transaction abort!
+  rollback completed
+  abort: pretxncommit.abort hook exited with status 1
+  [255]
+  $ cat >> .hg/hgrc <<EOF
+  > [hooks]
+  > pretxncommit.abort = !
+  > EOF
+
+  $ hg parents -T "{node|short}\n"
+  d11e3596cc1a
+  $ hg status -A
+  M r1
+  ? abort
+  C r2
+
   $ cd ..