mercurial/scmutil.py
changeset 34461 c67db5dc131d
parent 34460 910adadf08e8
child 34542 153e4e05e9b3
--- a/mercurial/scmutil.py	Sun Oct 01 11:58:27 2017 +0100
+++ b/mercurial/scmutil.py	Sun Oct 01 12:12:56 2017 +0100
@@ -13,6 +13,7 @@
 import os
 import re
 import socket
+import subprocess
 import weakref
 
 from .i18n import _
@@ -1038,20 +1039,18 @@
         raise error.Abort(_("unknown extdata source '%s'") % source)
 
     data = {}
-    if spec.startswith("shell:"):
-        # external commands should be run relative to the repo root
-        cmd = spec[6:]
-        cwd = os.getcwd()
-        os.chdir(repo.root)
-        try:
-            src = util.popen(cmd)
-        finally:
-            os.chdir(cwd)
-    else:
-        # treat as a URL or file
-        src = url.open(repo.ui, spec)
-
+    src = proc = None
     try:
+        if spec.startswith("shell:"):
+            # external commands should be run relative to the repo root
+            cmd = spec[6:]
+            proc = subprocess.Popen(cmd, shell=True, bufsize=-1,
+                                    close_fds=util.closefds,
+                                    stdout=subprocess.PIPE, cwd=repo.root)
+            src = proc.stdout
+        else:
+            # treat as a URL or file
+            src = url.open(repo.ui, spec)
         for l in src:
             if " " in l:
                 k, v = l.strip().split(" ", 1)
@@ -1064,7 +1063,10 @@
             except (error.LookupError, error.RepoLookupError):
                 pass # we ignore data for nodes that don't exist locally
     finally:
-        src.close()
+        if proc:
+            proc.communicate()
+        if src:
+            src.close()
 
     return data