Dulwich.io dulwich / e43edaf
Fix tests, add version support to index. Jelmer Vernooń≥ 14 days ago
4 changed file(s) with 40 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
772772
773773 def _remote_error_from_stderr(stderr):
774774 if stderr is None:
775 raise HangupException()
775 return HangupException()
776776 lines = [line.rstrip(b'\n') for line in stderr.readlines()]
777777 for line in lines:
778778 if line.startswith(b'ERROR: '):
779 raise GitProtocolError(
779 return GitProtocolError(
780780 line[len(b'ERROR: '):].decode('utf-8', 'replace'))
781 raise HangupException(lines)
781 return HangupException(lines)
782782
783783
784784 class TraditionalGitClient(GitClient):
830830 try:
831831 old_refs, server_capabilities = read_pkt_refs(proto)
832832 except HangupException:
833 _remote_error_from_stderr(stderr)
833 raise _remote_error_from_stderr(stderr)
834834 negotiated_capabilities, agent = \
835835 self._negotiate_receive_pack_capabilities(server_capabilities)
836836 if CAPABILITY_REPORT_STATUS in negotiated_capabilities:
910910 try:
911911 refs, server_capabilities = read_pkt_refs(proto)
912912 except HangupException:
913 _remote_error_from_stderr(stderr)
913 raise _remote_error_from_stderr(stderr)
914914 negotiated_capabilities, symrefs, agent = (
915915 self._negotiate_upload_pack_capabilities(
916916 server_capabilities))
947947 try:
948948 refs, _ = read_pkt_refs(proto)
949949 except HangupException:
950 _remote_error_from_stderr(stderr)
950 raise _remote_error_from_stderr(stderr)
951951 proto.write_pkt_line(None)
952952 return refs
953953
967967 try:
968968 pkt = proto.read_pkt_line()
969969 except HangupException:
970 _remote_error_from_stderr(stderr)
970 raise _remote_error_from_stderr(stderr)
971971 if pkt == b"NACK\n":
972972 return
973973 elif pkt == b"ACK\n":
116116 def __init__(self, *args, **kwargs):
117117 Exception.__init__(self, *args, **kwargs)
118118
119 def __eq__(self, other):
120 return isinstance(self, type(other)) and self.args == other.args
121
119122
120123 class SendPackError(GitProtocolError):
121124 """An error occurred during send_pack."""
145148 super(HangupException, self).__init__(
146149 "The remote server unexpectedly closed the connection.")
147150 self.stderr_lines = stderr_lines
151
152 def __eq__(self, other):
153 return (
154 isinstance(self, type(other)) and
155 self.stderr_lines == other.stderr_lines)
148156
149157
150158 class UnexpectedCommandError(GitProtocolError):
6666 FLAG_EXTENDED = 0x4000
6767
6868
69 DEFAULT_VERSION = 2
70
71
6972 def pathsplit(path):
7073 """Split a /-delimited path into a directory part and a basename.
7174
159162 f.write(b'\0' * ((beginoffset + real_size) - f.tell()))
160163
161164
162 def read_index(f):
165 def read_index(f: BinaryIO):
163166 """Read an index file, yielding the individual entries."""
164167 header = f.read(4)
165168 if header != b'DIRC':
182185 return ret
183186
184187
185 def write_index(f: BinaryIO, entries: List[Any], version: int = 4):
188 def write_index(
189 f: BinaryIO,
190 entries: List[Any], version: Optional[int] = None):
186191 """Write an index file.
187192
188193 Args:
190195 version: Version number to write
191196 entries: Iterable over the entries to write
192197 """
198 if version is None:
199 version = DEFAULT_VERSION
193200 f.write(b'DIRC')
194201 f.write(struct.pack(b'>LL', version, len(entries)))
195202 for x in entries:
196203 write_cache_entry(f, x)
197204
198205
199 def write_index_dict(f: BinaryIO, entries: Dict[bytes, IndexEntry]) -> None:
206 def write_index_dict(
207 f: BinaryIO, entries: Dict[bytes, IndexEntry],
208 version: Optional[int] = None) -> None:
200209 """Write an index file based on the contents of a dictionary.
201210
202211 """
203212 entries_list = []
204213 for name in sorted(entries):
205214 entries_list.append((name,) + tuple(entries[name]))
206 write_index(f, entries_list)
215 write_index(f, entries_list, version=version)
207216
208217
209218 def cleanup_mode(mode: int) -> int:
238247 filename: Path to the index file
239248 """
240249 self._filename = filename
250 # TODO(jelmer): Store the version returned by read_index
251 self._version = None
241252 self.clear()
242253 self.read()
243254
253264 f = GitFile(self._filename, 'wb')
254265 try:
255266 f = SHA1Writer(f)
256 write_index_dict(f, self._byname)
267 write_index_dict(f, self._byname, version=self._version)
257268 finally:
258269 f.close()
259270
361372
362373
363374 def commit_tree(
364 object_store: BaseObjectStore,
375 object_store: 'BaseObjectStore',
365376 blobs: Iterable[Tuple[bytes, bytes, int]]) -> bytes:
366377 """Commit a new tree.
367378
371382 Returns:
372383 SHA1 of the created tree.
373384 """
374
375385 trees: Dict[bytes, Any] = {b'': {}}
376386
377387 def add_tree(path):
404414 return build_tree(b'')
405415
406416
407 def commit_index(object_store: BaseObjectStore, index: Index) -> bytes:
417 def commit_index(object_store: 'BaseObjectStore', index: Index) -> bytes:
408418 """Create a new tree from an index.
409419
410420 Args:
419429 def changes_from_tree(
420430 names: Iterable[bytes],
421431 lookup_entry: Callable[[bytes], Tuple[bytes, int]],
422 object_store: BaseObjectStore, tree: Optional[bytes],
432 object_store: 'BaseObjectStore', tree: Optional[bytes],
423433 want_unchanged=False) -> Iterable[
424434 Tuple[
425435 Tuple[Optional[bytes], Optional[bytes]],
797807
798808
799809 def iter_fresh_entries(
800 paths, root_path, object_store: Optional[BaseObjectStore] = None):
810 paths, root_path, object_store: Optional['BaseObjectStore'] = None):
801811 """Iterate over current versions of index entries on disk.
802812
803813 Args:
4747 StrangeHostname,
4848 SubprocessSSHVendor,
4949 PLinkSSHVendor,
50 HangupException,
51 GitProtocolError,
5052 check_wants,
5153 default_urllib3_manager,
5254 get_credentials_from_store,
13621364 class RemoteErrorFromStderrTests(TestCase):
13631365
13641366 def test_nothing(self):
1365 self.assertIs(_remote_error_from_stderr(None), None)
1367 self.assertEqual(
1368 _remote_error_from_stderr(None), HangupException())
13661369
13671370 def test_error_line(self):
13681371 b = BytesIO(b"""\
13721375 """)
13731376 self.assertEqual(
13741377 _remote_error_from_stderr(b),
1375 "This is the actual error")
1378 GitProtocolError("This is the actual error"))
13761379
13771380 def test_no_error_line(self):
13781381 b = BytesIO(b"""\