changeset 28586:82cee85d5274

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.
author Jun Wu <quark@fb.com>
date Thu, 17 Mar 2016 18:27:48 +0000
parents a3f3fdac8433
children 76d7cab13f04
files hgext/chgserver.py
diffstat 1 files changed, 9 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/chgserver.py	Sat Mar 12 14:04:57 2016 -0800
+++ b/hgext/chgserver.py	Thu Mar 17 18:27:48 2016 +0000
@@ -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):