|
22 | 22 | from itertools import chain
|
23 | 23 |
|
24 | 24 |
|
25 |
| -__all__ = ('ObjectDBR', 'ObjectDBW', 'FileDBBase', 'CompoundDB', 'CachingDB') |
| 25 | +__all__ = ( 'ObjectDBR', 'ObjectDBW', 'FileDBBase', 'CompoundDB', 'CachingDB', |
| 26 | + 'TransportDBMixin', 'RefSpec', 'FetchInfo', 'PushInfo') |
26 | 27 |
|
27 | 28 |
|
28 | 29 | class ObjectDBR(object):
|
@@ -321,5 +322,133 @@ def partial_to_complete_sha_hex(self, partial_hexsha):
|
321 | 322 | return candidate
|
322 | 323 |
|
323 | 324 | #} END interface
|
| 325 | + |
| 326 | + |
| 327 | +class RefSpec(object): |
| 328 | + """A refspec is a simple container which provides information about the way |
| 329 | + something should be fetched or pushed. It requires to use symbols to describe |
| 330 | + the actual objects which is done using reference names (or respective instances |
| 331 | + which resolve to actual reference names).""" |
| 332 | + __slots__ = ('source', 'destination', 'force') |
| 333 | + |
| 334 | + def __init__(self, source, destination, force=False): |
| 335 | + """initalize the instance with the required values |
| 336 | + :param source: reference name or instance. If None, the Destination |
| 337 | + is supposed to be deleted.""" |
| 338 | + self.source = source |
| 339 | + self.destination = destination |
| 340 | + self.force = force |
| 341 | + if self.destination is None: |
| 342 | + raise ValueError("Destination must be set") |
| 343 | + |
| 344 | + def __str__(self): |
| 345 | + """:return: a git-style refspec""" |
| 346 | + s = str(self.source) |
| 347 | + if self.source is None: |
| 348 | + s = '' |
| 349 | + #END handle source |
| 350 | + d = str(self.destination) |
| 351 | + p = '' |
| 352 | + if self.force: |
| 353 | + p = '+' |
| 354 | + #END handle force |
| 355 | + res = "%s%s:%s" % (p, s, d) |
| 356 | + |
| 357 | + def delete_destination(self): |
| 358 | + return self.source is None |
| 359 | + |
| 360 | + |
| 361 | +class PushInfo(object): |
| 362 | + """A type presenting information about the result of a push operation for exactly |
| 363 | + one refspec |
| 364 | +
|
| 365 | + flags # bitflags providing more information about the result |
| 366 | + local_ref # Reference pointing to the local reference that was pushed |
| 367 | + # It is None if the ref was deleted. |
| 368 | + remote_ref_string # path to the remote reference located on the remote side |
| 369 | + remote_ref # Remote Reference on the local side corresponding to |
| 370 | + # the remote_ref_string. It can be a TagReference as well. |
| 371 | + old_commit # commit at which the remote_ref was standing before we pushed |
| 372 | + # it to local_ref.commit. Will be None if an error was indicated |
| 373 | + summary # summary line providing human readable english text about the push |
| 374 | + """ |
| 375 | + __slots__ = tuple() |
| 376 | + |
| 377 | + NEW_TAG, NEW_HEAD, NO_MATCH, REJECTED, REMOTE_REJECTED, REMOTE_FAILURE, DELETED, \ |
| 378 | + FORCED_UPDATE, FAST_FORWARD, UP_TO_DATE, ERROR = [ 1 << x for x in range(11) ] |
| 379 | + |
| 380 | + |
| 381 | +class FetchInfo(object): |
| 382 | + """A type presenting information about the fetch operation on exactly one refspec |
| 383 | + |
| 384 | + The following members are defined: |
| 385 | + ref # name of the reference to the changed |
| 386 | + # remote head or FETCH_HEAD. Implementations can provide |
| 387 | + # actual class instance which convert to a respective string |
| 388 | + flags # additional flags to be & with enumeration members, |
| 389 | + # i.e. info.flags & info.REJECTED |
| 390 | + # is 0 if ref is FETCH_HEAD |
| 391 | + note # additional notes given by the fetch-pack implementation intended for the user |
| 392 | + old_commit # if info.flags & info.FORCED_UPDATE|info.FAST_FORWARD, |
| 393 | + # field is set to the previous location of ref as hexsha or None |
| 394 | + # Implementors may use their own type too, but it should decay into a |
| 395 | + # string of its hexadecimal sha representation""" |
| 396 | + __slots__ = tuple() |
| 397 | + |
| 398 | + NEW_TAG, NEW_HEAD, HEAD_UPTODATE, TAG_UPDATE, REJECTED, FORCED_UPDATE, \ |
| 399 | + FAST_FORWARD, ERROR = [ 1 << x for x in range(8) ] |
| 400 | + |
| 401 | + |
| 402 | +class TransportDBMixin(object): |
| 403 | + """A database which allows to transport objects from and to different locations |
| 404 | + which are specified by urls (location) and refspecs (what to transport, |
| 405 | + see http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html). |
| 406 | + |
| 407 | + At the beginning of a transport operation, it will be determined which objects |
| 408 | + have to be sent (either by this or by the other side). |
| 409 | + |
| 410 | + Afterwards a pack with the required objects is sent (or received). If there is |
| 411 | + nothing to send, the pack will be empty. |
| 412 | + |
| 413 | + The communication itself if implemented using a protocol instance which deals |
| 414 | + with the actual formatting of the lines sent.""" |
| 415 | + # The following variables need to be set by the derived class |
| 416 | + #{Configuration |
| 417 | + protocol = None |
| 418 | + #}end configuraiton |
| 419 | + |
| 420 | + #{ Interface |
| 421 | + |
| 422 | + def fetch(self, url, refspecs, progress=None): |
| 423 | + """Fetch the objects defined by the given refspec from the given url. |
| 424 | + :param url: url identifying the source of the objects. It may also be |
| 425 | + a symbol from which the respective url can be resolved, like the |
| 426 | + name of the remote. The implementation should allow objects as input |
| 427 | + as well, these are assumed to resovle to a meaningful string though. |
| 428 | + :param refspecs: iterable of reference specifiers or RefSpec instance, |
| 429 | + identifying the references to be fetch from the remote. |
| 430 | + :param progress: callable which receives progress messages for user consumption |
| 431 | + :return: List of binary object shas matching the respective remote ref which |
| 432 | + was previously fetched, in the order of the input refspecs. |
| 433 | + :note: even if the operation fails, one of the returned FetchInfo instances |
| 434 | + may still contain errors or failures in only part of the refspecs. |
| 435 | + :raise: if any issue occours during the transport or if the url is not |
| 436 | + supported by the protocol. |
| 437 | + """ |
| 438 | + raise NotImplementedError() |
324 | 439 |
|
| 440 | + def push(self, url, refspecs, progress=None): |
| 441 | + """Transport the objects identified by the given refspec to the remote |
| 442 | + at the given url. |
| 443 | + :param url: Decribes the location which is to receive the objects |
| 444 | + see fetch() for more details |
| 445 | + :param refspecs: iterable of refspecs strings or RefSpec instances |
| 446 | + to identify the objects to push |
| 447 | + :param progress: see fetch() |
| 448 | + :todo: what to return ? |
| 449 | + :raise: if any issue arises during transport or if the url cannot be handled""" |
| 450 | + raise NotImplementedError() |
| 451 | + |
| 452 | + #}end interface |
| 453 | + |
325 | 454 |
|
0 commit comments