Patchwork [V2] chgserver: use old ui.system if fout is not stdout or needs to be captured

login
register
mail settings
Submitter Jun Wu
Date March 19, 2016, 6:15 p.m.
Message ID <45e048623bd45fa3fa94.1458411343@x1c>
Download mbox | patch
Permalink /patch/13956/
State Accepted
Delegated to: Yuya Nishihara
Headers show

Comments

Jun Wu - March 19, 2016, 6:15 p.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1458239268 0
#      Thu Mar 17 18:27:48 2016 +0000
# Node ID 45e048623bd45fa3fa949de743a4aaef18ffb5a0
# Parent  1435a8e9b5fe38cfe900e0a75fefab046af73dd6
chgserver: use old ui.system if fout is not stdout or needs to be captured

Before this patch, chgui will override the system method, forwarding every
process execution to the client so sessions and process groups can work as
expected. But the chg client will just use stdout, if ui.fout is not stdout or
if the output is set to be captured to safe._buffers, the client will not
behave correctly.

This can happen especially with code prepending "remote:". For example, bundle2
uses ui.pushbuffer, and sshpeer sets fout to ferr. We may have trouble with
interactive commands in the fout set to ferr case but if it really bites us, we
can always send file descriptors to the client.

This patch adds a check to detect the above situations and fallback to the old
ui.system if so. It will make chg happy with test-bundle2-exchange.t,
test-phases-exchange.t, test-ssh-bundle1.t and test-ssh.t.
Yuya Nishihara - March 19, 2016, 6:57 p.m.
On Sat, 19 Mar 2016 11:15:43 -0700, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <quark@fb.com>
> # Date 1458239268 0
> #      Thu Mar 17 18:27:48 2016 +0000
> # Node ID 45e048623bd45fa3fa949de743a4aaef18ffb5a0
> # Parent  1435a8e9b5fe38cfe900e0a75fefab046af73dd6
> chgserver: use old ui.system if fout is not stdout or needs to be captured

Queued this, thanks!

Patch

diff --git a/hgext/chgserver.py b/hgext/chgserver.py
--- a/hgext/chgserver.py
+++ b/hgext/chgserver.py
@@ -235,6 +235,15 @@ 
 
         def system(self, cmd, environ=None, cwd=None, onerr=None,
                    errprefix=None):
+            # fallback to the original system method if the output needs to be
+            # captured (to self._buffers), or the output stream is not stdout
+            # (e.g. stderr, cStringIO), because the chg client is not aware of
+            # these situations and will behave differently (write to stdout).
+            if any(s[1] for s in self._bufferstates) \
+               or not util.safehasattr(self.fout, 'fileno') \
+               or self.fout.fileno() != sys.stdout.fileno():
+                return super(chgui, self).system(cmd, environ, cwd, onerr,
+                                                 errprefix)
             # copied from mercurial/util.py:system()
             self.flush()
             def py2shell(val):