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