소스 검색

Add a generic class that can talk to any git-receive-pack or git-upload-packs that we can get pipe access to

John Carr 16 년 전
부모
커밋
9ce572f161
2개의 변경된 파일53개의 추가작업 그리고 6개의 파일을 삭제
  1. 6 6
      bin/dulwich
  2. 47 0
      dulwich/client.py

+ 6 - 6
bin/dulwich

@@ -137,7 +137,7 @@ def cmd_init(args):
 
 
 def cmd_clone(args):
-	from dulwich.client import TCPGitClient, SimpleFetchGraphWalker
+	from dulwich.client import TCPGitClient, SubprocessGitClient, SimpleFetchGraphWalker
 	from dulwich.repo import Repo
 	import os
 	import sys
@@ -148,12 +148,12 @@ def cmd_clone(args):
 		print "usage: dulwich clone host:path [PATH]"
 		sys.exit(1)
 
-	if not ":" in args[0]:
-		print "Usage: dulwich clone host:path [PATH]"
-		sys.exit(1)
+	#if not ":" in args[0]:
+	#	print "Usage: dulwich clone host:path [PATH]"
+	#	sys.exit(1)
 	(host, host_path) = args.pop(0).split(":", 1)
-	client = TCPGitClient(host)
-
+	#client = TCPGitClient(host)
+	client = SubprocessGitClient(host)
 	if len(args) > 0:
 		path = args.pop(0)
 	else:

+ 47 - 0
dulwich/client.py

@@ -16,8 +16,10 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.
 
+import os
 import select
 import socket
+import subprocess
 from dulwich.protocol import Protocol, TCP_GIT_PORT, extract_capabilities
 
 class SimpleFetchGraphWalker(object):
@@ -152,3 +154,48 @@ class TCPGitClient(GitClient):
     def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress):
         self.proto.send_cmd("git-upload-pack", path, "host=%s" % self.host)
         super(TCPGitClient, self).fetch_pack(path, determine_wants, graph_walker, pack_data, progress)
+
+
+class SubprocessSocket(object):
+    """A socket-like object that talks to an ssh subprocess via pipes."""
+
+    def __init__(self, proc):
+        self.proc = proc
+
+    def send(self, data):
+        return os.write(self.proc.stdin.fileno(), data)
+
+    def recv(self, count):
+        return os.read(self.proc.stdout.fileno(), count)
+
+    def close(self):
+        self.proc.stdin.close()
+        self.proc.stdout.close()
+        self.proc.wait()
+
+    def get_filelike_channels(self):
+        return (self.proc.stdout, self.proc.stdin)
+
+
+class SubprocessGitClient(GitClient):
+
+    def __init__(self, host, port=None):
+        self.host = host
+        self.port = port
+
+    def _connect(self, service, *args):
+        argv = [service] + list(args)
+        proc = subprocess.Popen(argv,
+                                stdin=subprocess.PIPE,
+                                stdout=subprocess.PIPE)
+        socket = SubprocessSocket(proc)
+        return GitClient(proc.stdin.fileno(), socket.recv, socket.send)
+
+    def send_pack(self, path):
+        client = self._connect("git-receive-pack", path)
+        client.send_pack(path)
+
+    def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress):
+        client = self._connect("git-upload-pack", path)
+        client.fetch_pack(path, determine_wants, graph_walker, pack_data, progress)
+