Kiln » Dependencies » Dulwich Read More
Clone URL:  
Pushed to one repository · View In Graph Contained in master-1, master-0, and 0.9.4

Implement HTTPGitClient._read_references.

Changeset d67ecb373569

Parent 7057395ff809

by Jelmer Vernooij

Changes to 2 files · Browse files at d67ecb373569 Showing diff from parent 7057395ff809 Diff from another changeset...

Change 1 of 8 Show Entire File dulwich/​client.py Stacked
 
24
25
26
 
27
28
29
 
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
 
150
151
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
154
155
 
416
417
418
419
 
420
421
422
 
423
 
 
 
 
 
424
425
426
 
428
429
430
431
 
 
 
 
 
 
 
 
 
 
 
432
433
434
 
441
442
443
 
 
444
445
446
 
452
453
454
 
 
455
456
457
 
467
468
469
 
 
 
470
471
472
 
24
25
26
27
28
29
30
 
78
79
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
82
83
 
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 
417
418
419
 
420
421
422
 
423
424
425
426
427
428
429
430
431
432
 
434
435
436
 
437
438
439
440
441
442
443
444
445
446
447
448
449
450
 
457
458
459
460
461
462
463
464
 
470
471
472
473
474
475
476
477
 
487
488
489
490
491
492
493
494
495
@@ -24,6 +24,7 @@
 import select  import socket  import subprocess +import urllib2  import urlparse    from dulwich.errors import ( @@ -77,67 +78,6 @@
  if thin_packs:   self._fetch_capabilities.append('thin-pack')   - def send_pack(self, path, determine_wants, generate_pack_contents): - """Upload a pack to a remote repository. - - :param path: Repository path - :param generate_pack_contents: Function that can return a sequence of the - shas of the objects to upload. - - :raises SendPackError: if server rejects the pack data - :raises UpdateRefsError: if the server supports report-status - and rejects ref updates - """ - raise NotImplementedError(self.send_pack) - - def fetch(self, path, target, determine_wants=None, progress=None): - """Fetch into a target repository. - - :param path: Path to fetch from - :param target: Target repository to fetch into - :param determine_wants: Optional function to determine what refs - to fetch - :param progress: Optional progress function - :return: remote refs - """ - if determine_wants is None: - determine_wants = target.object_store.determine_wants_all - f, commit = target.object_store.add_pack() - try: - return self.fetch_pack(path, determine_wants, - target.get_graph_walker(), f.write, progress) - finally: - commit() - - def fetch_pack(self, path, determine_wants, graph_walker, pack_data, - progress): - """Retrieve a pack from a git smart server. - - :param determine_wants: Callback that returns list of commits to fetch - :param graph_walker: Object with next() and ack(). - :param pack_data: Callback called for each bit of data in the pack - :param progress: Callback for progress reports (strings) - """ - raise NotImplementedError(self.fetch_pack) - - -class TraditionalGitClient(GitClient): - """Traditional Git client.""" - - def _connect(self, cmd, path): - """Create a connection to the server. - - This method is abstract - concrete implementations should - implement their own variant which connects to the server and - returns an initialized Protocol object with the service ready - for use and a can_read function which may be used to see if - reads would block. - - :param cmd: The git service name to which we should connect. - :param path: The path we should pass to the service. - """ - raise NotImplementedError() -   def _read_refs(self, proto):   server_capabilities = None   refs = {} @@ -150,6 +90,67 @@
  (ref, server_capabilities) = extract_capabilities(ref)   refs[ref] = sha   return refs, server_capabilities + + def send_pack(self, path, determine_wants, generate_pack_contents): + """Upload a pack to a remote repository. + + :param path: Repository path + :param generate_pack_contents: Function that can return a sequence of the + shas of the objects to upload. + + :raises SendPackError: if server rejects the pack data + :raises UpdateRefsError: if the server supports report-status + and rejects ref updates + """ + raise NotImplementedError(self.send_pack) + + def fetch(self, path, target, determine_wants=None, progress=None): + """Fetch into a target repository. + + :param path: Path to fetch from + :param target: Target repository to fetch into + :param determine_wants: Optional function to determine what refs + to fetch + :param progress: Optional progress function + :return: remote refs + """ + if determine_wants is None: + determine_wants = target.object_store.determine_wants_all + f, commit = target.object_store.add_pack() + try: + return self.fetch_pack(path, determine_wants, + target.get_graph_walker(), f.write, progress) + finally: + commit() + + def fetch_pack(self, path, determine_wants, graph_walker, pack_data, + progress): + """Retrieve a pack from a git smart server. + + :param determine_wants: Callback that returns list of commits to fetch + :param graph_walker: Object with next() and ack(). + :param pack_data: Callback called for each bit of data in the pack + :param progress: Callback for progress reports (strings) + """ + raise NotImplementedError(self.fetch_pack) + + +class TraditionalGitClient(GitClient): + """Traditional Git client.""" + + def _connect(self, cmd, path): + """Create a connection to the server. + + This method is abstract - concrete implementations should + implement their own variant which connects to the server and + returns an initialized Protocol object with the service ready + for use and a can_read function which may be used to see if + reads would block. + + :param cmd: The git service name to which we should connect. + :param path: The path we should pass to the service. + """ + raise NotImplementedError()     def _parse_status_report(self, proto):   unpack = proto.read_pkt_line().strip() @@ -416,11 +417,16 @@
   class HttpGitClient(GitClient):   - def __init__(self, host, port=None, username=None, force_dumb=False, *args, **kwargs): + def __init__(self, host, port=None, username=None, password=None, dumb=None, *args, **kwargs):   self.host = host   self.port = port - self.force_dumb = force_dumb + self.dumb = dumb   self.username = username + self.password = password + netloc = self.host + if self.port: + netloc += ":%d" % self.port + self.url = "http://%s/" % netloc   GitClient.__init__(self, *args, **kwargs)     @classmethod @@ -428,7 +434,17 @@
  parsed = urlparse.urlparse(url)   assert parsed.scheme == 'http'   return cls(parsed.hostname, port=parsed.port, username=parsed.port, - password=parsed.password) + password=parsed.password), parsed.path + + def _discover_references(self, service, url): + url = urlparse.urljoin(url+"/", "info/refs") + if not self.dumb: + url += "?service=%s" % service + req = urllib2.Request(url) + resp = urllib2.urlopen(req) + self.dumb = (not resp.info().gettype().startswith("application/x-git-")) + proto = Protocol(resp.read, None, report_activity=self._report_activity) + return self._read_refs(proto)     def send_pack(self, path, determine_wants, generate_pack_contents):   """Upload a pack to a remote repository. @@ -441,6 +457,8 @@
  :raises UpdateRefsError: if the server supports report-status   and rejects ref updates   """ + url = urlparse.urljoin(self.url, path) + refs, server_capabilities = self._discover_references("git-upload-pack", url)   raise NotImplementedError(self.send_pack)     def fetch_pack(self, path, determine_wants, graph_walker, pack_data, @@ -452,6 +470,8 @@
  :param pack_data: Callback called for each bit of data in the pack   :param progress: Callback for progress reports (strings)   """ + url = urlparse.urljoin(self.url, path) + refs, server_capabilities = self._discover_references("git-receive-pack", url)   raise NotImplementedError(self.fetch_pack)     @@ -467,6 +487,9 @@
  elif parsed.scheme == 'git+ssh':   return SSHGitClient(parsed.hostname, port=parsed.port,   username=parsed.username), parsed.path + elif parsed.scheme == 'http': + return HttpGitClient(parsed.hostname, port=parsed.port, + username=parsed.username), parsed.path     if parsed.scheme and not parsed.netloc:   # SSH with no user@, zero or one leading slash.
 
30
31
32
 
33
34
35
 
296
297
298
 
299
300
301
 
369
370
371
372
 
373
374
375
 
405
406
407
408
 
409
410
411
 
414
415
416
417
 
 
418
419
420
 
 
30
31
32
33
34
35
36
 
297
298
299
300
301
302
303
 
371
372
373
 
374
375
376
377
 
407
408
409
 
410
411
412
413
 
416
417
418
 
419
420
421
422
 
423
@@ -30,6 +30,7 @@
 import tempfile  import threading  import urllib +import urlparse    from dulwich import (   client, @@ -296,6 +297,7 @@
  env['SERVER_PROTOCOL'] = self.protocol_version   env['SERVER_PORT'] = str(self.server.server_port)   env['GIT_PROJECT_ROOT'] = self.server.root_path + env["GIT_HTTP_EXPORT_ALL"] = "1"   env['REQUEST_METHOD'] = self.command   uqrest = urllib.unquote(rest)   env['PATH_INFO'] = uqrest @@ -369,7 +371,7 @@
  while select.select([self.rfile._sock], [], [], 0)[0]:   if not self.rfile._sock.recv(1):   break - args = ['http-backend'] + args = ['-c', 'http.uploadpack=true', '-c', 'http.receivepack=true', 'http-backend']   if '=' not in decoded_query:   args.append(decoded_query)   stdout = run_git_or_fail(args, input=data, env=env, stderr=subprocess.PIPE) @@ -405,7 +407,7 @@
  def setUp(self):   CompatTestCase.setUp(self)   DulwichClientTestBase.setUp(self) - self._httpd = HTTPGitServer(("localhost", 8080), self.gitroot) + self._httpd = HTTPGitServer(("localhost", 0), self.gitroot)   self.addCleanup(self._httpd.shutdown)   threading.Thread(target=self._httpd.serve_forever).start()   @@ -414,7 +416,8 @@
  CompatTestCase.tearDown(self)     def _client(self): - return client.HttpGitClient(self._httpd.get_url()) + ret, self._path = client.HttpGitClient.from_url(self._httpd.get_url()) + return ret     def _build_path(self, path): - return path + return urlparse.urljoin(self._path.strip("/"), path.strip("/"))