merge with stable
authorAugie Fackler <augie@google.com>
Wed, 22 Jul 2020 22:09:38 -0400
changeset 45205 4b923da0cb86
parent 45204 ce9ee81df9ff (current diff)
parent 45191 fc54f52779dd (diff)
child 45206 db0be4678399
merge with stable
--- a/.hgsigs	Tue Jul 07 00:18:15 2020 +0200
+++ b/.hgsigs	Wed Jul 22 22:09:38 2020 -0400
@@ -198,3 +198,4 @@
 cf3e07d7648a4371ce584d15dd692e7a6845792f 0 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
+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
--- a/.hgtags	Tue Jul 07 00:18:15 2020 +0200
+++ b/.hgtags	Wed Jul 22 22:09:38 2020 -0400
@@ -211,3 +211,4 @@
 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
+28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
--- a/hgext/infinitepush/store.py	Tue Jul 07 00:18:15 2020 +0200
+++ b/hgext/infinitepush/store.py	Wed Jul 22 22:09:38 2020 -0400
@@ -20,8 +20,6 @@
     procutil,
 )
 
-NamedTemporaryFile = tempfile.NamedTemporaryFile
-
 
 class BundleWriteException(Exception):
     pass
@@ -108,6 +106,23 @@
             return None
 
 
+def format_placeholders_args(args, filename=None, handle=None):
+    """Formats `args` with Infinitepush replacements.
+
+    Hack to get `str.format()`-ed strings working in a BC way with
+    bytes.
+    """
+    formatted_args = []
+    for arg in args:
+        if filename and arg == b'{filename}':
+            formatted_args.append(filename)
+        elif handle and arg == b'{handle}':
+            formatted_args.append(handle)
+        else:
+            formatted_args.append(arg)
+    return formatted_args
+
+
 class externalbundlestore(abstractbundlestore):
     def __init__(self, put_binary, put_args, get_binary, get_args):
         """
@@ -142,13 +157,13 @@
         # closing it
         # TODO: rewrite without str.format() and replace NamedTemporaryFile()
         # with pycompat.namedtempfile()
-        with NamedTemporaryFile() as temp:
+        with pycompat.namedtempfile() as temp:
             temp.write(data)
             temp.flush()
             temp.seek(0)
-            formatted_args = [
-                arg.format(filename=temp.name) for arg in self.put_args
-            ]
+            formatted_args = format_placeholders_args(
+                self.put_args, filename=temp.name
+            )
             returncode, stdout, stderr = self._call_binary(
                 [self.put_binary] + formatted_args
             )
@@ -168,13 +183,10 @@
     def read(self, handle):
         # Won't work on windows because you can't open file second time without
         # closing it
-        # TODO: rewrite without str.format() and replace NamedTemporaryFile()
-        # with pycompat.namedtempfile()
-        with NamedTemporaryFile() as temp:
-            formatted_args = [
-                arg.format(filename=temp.name, handle=handle)
-                for arg in self.get_args
-            ]
+        with pycompat.namedtempfile() as temp:
+            formatted_args = format_placeholders_args(
+                self.get_args, filename=temp.name, handle=handle
+            )
             returncode, stdout, stderr = self._call_binary(
                 [self.get_binary] + formatted_args
             )
--- a/mercurial/chgserver.py	Tue Jul 07 00:18:15 2020 +0200
+++ b/mercurial/chgserver.py	Wed Jul 22 22:09:38 2020 -0400
@@ -434,8 +434,11 @@
             self._oldios.append((ch, fp, fd))
 
     def _restoreio(self):
+        if not self._oldios:
+            return
+        nullfd = os.open(os.devnull, os.O_WRONLY)
         ui = self.ui
-        for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels):
+        for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
             newfp = getattr(ui, fn)
             # close newfp while it's associated with client; otherwise it
             # would be closed when newfp is deleted
@@ -443,6 +446,12 @@
                 newfp.close()
             # restore original fd: fp is open again
             try:
+                if newfp is fp and 'w' in mode:
+                    # Discard buffered data which couldn't be flushed because
+                    # of EPIPE. The data should belong to the current session
+                    # and should never persist.
+                    os.dup2(nullfd, fp.fileno())
+                    fp.flush()
                 os.dup2(fd, fp.fileno())
             except OSError as err:
                 # According to issue6330, running chg on heavy loaded systems
@@ -459,6 +468,7 @@
             os.close(fd)
             setattr(self, cn, ch)
             setattr(ui, fn, fp)
+        os.close(nullfd)
         del self._oldios[:]
 
     def validate(self):
--- a/relnotes/next	Tue Jul 07 00:18:15 2020 +0200
+++ b/relnotes/next	Wed Jul 22 22:09:38 2020 -0400
@@ -11,6 +11,7 @@
  * Phases processing is much faster, especially for repositories with
    old non-public changesets.
 
+
 == New Experimental Features ==
 
  * The core of some hg operations have been (and are being)
@@ -20,16 +21,45 @@
    windows. See rust/README.rst in the mercurial repository for
    instructions to opt into this.
 
+ * An experimental config `rewrite.empty-successor` was introduced to control
+   what happens when rewrite operations result in empty changesets.
+
+
+== Bug Fixes ==
+
+ * For the case when connected to a TTY, stdout was fixed to be line-buffered
+   on Python 3 (where it was block-buffered before, causing the process to seem
+   hanging) and Windows on Python 2 (where it was unbuffered before).
+
+ * Subversion sources of the convert extension were fixed to work on Python 3.
+
+ * Subversion sources of the convert extension now interpret the encoding of
+   URLs like Subversion. Previously, there were situations where the convert
+   extension recognized a repository as present but Subversion did not, and
+   vice versa.
+
+ * The empty changeset check of in-memory rebases was fixed to match that of
+   normal rebases (and that of the commit command).
+
+ * The push command now checks the correct set of outgoing changesets for
+   obsolete and unstable changesets. Previously, it could happen that the check
+   prevented pushing changesets which were already on the server.
+
+
 == Backwards Compatibility Changes ==
 
-* Mercurial now requires at least Python 2.7.9 or a Python version that
-  backported modern SSL/TLS features (as defined in PEP 466), and that Python
-  was compiled against a OpenSSL version supporting TLS 1.1 or TLS 1.2
-  (likely this requires the OpenSSL version to be at least 1.0.1).
+ * Mercurial now requires at least Python 2.7.9 or a Python version that
+   backported modern SSL/TLS features (as defined in PEP 466), and that Python
+   was compiled against a OpenSSL version supporting TLS 1.1 or TLS 1.2
+   (likely this requires the OpenSSL version to be at least 1.0.1).
+ 
+ * The `hg perfwrite` command from contrib/perf.py was made more flexible and
+   changed its default behavior. To get the previous behavior, run `hg perfwrite
+   --nlines=100000 --nitems=1 --item='Testing write performance' --batch-line`.
 
-* The `hg perfwrite` command from contrib/perf.py was made more flexible and
-  changed its default behavior. To get the previous behavior, run `hg perfwrite
-  --nlines=100000 --nitems=1 --item='Testing write performance' --batch-line`.
+ * The absorb extension now preserves changesets with no file changes that can
+   be created by the commit command (those which change the branch name
+   compared to the parent and those closing a branch head).
 
 
 == Internal API Changes ==
@@ -43,3 +73,8 @@
    New accessors are provided to detect if any non-public changeset exists
    (`hasnonpublicphases`) and get the correponsponding root set
    (`nonpublicphaseroots`).
+
+ * The `stdin`, `stdout` and `stderr` attributes of the `mercurial.pycompat`
+   module were removed. Instead, the attributes of same name from the
+   `mercurial.utils.procutil` module should be used, which provide more
+   consistent behavior across Python versions and platforms.
--- a/tests/hghave.py	Tue Jul 07 00:18:15 2020 +0200
+++ b/tests/hghave.py	Wed Jul 22 22:09:38 2020 -0400
@@ -591,7 +591,7 @@
 
 @check("clang-format", "clang-format C code formatter")
 def has_clang_format():
-    m = matchoutput('clang-format --version', br'clang-format version (\d*)')
+    m = matchoutput('clang-format --version', br'clang-format version (\d+)')
     # style changed somewhere between 4.x and 6.x
     return m and int(m.group(1)) >= 6
 
--- a/tests/test-chg.t	Tue Jul 07 00:18:15 2020 +0200
+++ b/tests/test-chg.t	Wed Jul 22 22:09:38 2020 -0400
@@ -152,6 +152,49 @@
   crash-pager: going to crash
   [255]
 
+no stdout data should be printed after pager quits, and the buffered data
+should never persist (issue6207)
+
+"killed!" may be printed if terminated by SIGPIPE, which isn't important
+in this test.
+
+  $ cat > $TESTTMP/bulkwrite.py <<'EOF'
+  > import time
+  > from mercurial import error, registrar
+  > cmdtable = {}
+  > command = registrar.command(cmdtable)
+  > @command(b'bulkwrite')
+  > def bulkwrite(ui, repo, *pats, **opts):
+  >     ui.write(b'going to write massive data\n')
+  >     ui.flush()
+  >     t = time.time()
+  >     while time.time() - t < 2:
+  >         ui.write(b'x' * 1023 + b'\n')  # will be interrupted by SIGPIPE
+  >     raise error.Abort(b"write() doesn't block")
+  > EOF
+
+  $ cat > $TESTTMP/fakepager.py <<'EOF'
+  > import sys
+  > import time
+  > sys.stdout.write('paged! %r\n' % sys.stdin.readline())
+  > time.sleep(1)  # new data will be written
+  > EOF
+
+  $ cat >> .hg/hgrc <<EOF
+  > [extensions]
+  > bulkwrite = $TESTTMP/bulkwrite.py
+  > EOF
+
+  $ chg bulkwrite --pager=on --color no --config ui.formatted=True
+  paged! 'going to write massive data\n'
+  killed! (?)
+  [255]
+
+  $ chg bulkwrite --pager=on --color no --config ui.formatted=True
+  paged! 'going to write massive data\n'
+  killed! (?)
+  [255]
+
   $ cd ..
 
 server lifecycle
@@ -366,7 +409,7 @@
 
   $ cat log/server.log | filterlog
   YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...)
-  YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...)
+  YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...) (?)
   YYYY/MM/DD HH:MM:SS (PID)> init cached
   YYYY/MM/DD HH:MM:SS (PID)> id -R cached
   YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in  ...s)