77Module implementing a remote object allowing easy access to git remotes
88"""
99
10+ from errors import GitCommandError
1011from git .utils import LazyMixin , Iterable , IterableList
1112from objects import Commit
1213from refs import Reference , RemoteReference , SymbolicReference , TagReference
14+
1315import re
1416import os
1517
@@ -146,6 +148,7 @@ class PushInfo(object):
146148 info = remote.push()[0]
147149 info.flags # bitflags providing more information about the result
148150 info.local_ref # Reference pointing to the local reference that was pushed
151+ # It is None if the ref was deleted.
149152 info.remote_ref_string # path to the remote reference located on the remote side
150153 info.remote_ref # Remote Reference on the local side corresponding to
151154 # the remote_ref_string. It can be a TagReference as well.
@@ -154,8 +157,8 @@ class PushInfo(object):
154157 """
155158 __slots__ = ('local_ref' , 'remote_ref_string' , 'flags' , 'old_commit' , '_remote' )
156159
157- NO_MATCH , REJECTED , REMOTE_REJECTED , REMOTE_FAILURE , DELETED , \
158- FORCED_UPDATE , FAST_FORWARD , UP_TO_DATE , ERROR = [ 1 << x for x in range (9 ) ]
160+ NEW_TAG , NEW_HEAD , NO_MATCH , REJECTED , REMOTE_REJECTED , REMOTE_FAILURE , DELETED , \
161+ FORCED_UPDATE , FAST_FORWARD , UP_TO_DATE , ERROR = [ 1 << x for x in range (11 ) ]
159162
160163 _flag_map = { 'X' : NO_MATCH , '-' : DELETED , '*' : 0 ,
161164 '+' : FORCED_UPDATE , ' ' : FAST_FORWARD ,
@@ -194,6 +197,7 @@ def _from_line(cls, remote, line):
194197 Create a new PushInfo instance as parsed from line which is expected to be like
195198 c refs/heads/master:refs/heads/master 05d2687..1d0568e
196199 """
200+ print line
197201 control_character , from_to , summary = line .split ('\t ' , 3 )
198202 flags = 0
199203
@@ -206,7 +210,10 @@ def _from_line(cls, remote, line):
206210
207211 # from_to handling
208212 from_ref_string , to_ref_string = from_to .split (':' )
209- from_ref = Reference .from_path (remote .repo , from_ref_string )
213+ if flags & cls .DELETED :
214+ from_ref = None
215+ else :
216+ from_ref = Reference .from_path (remote .repo , from_ref_string )
210217
211218 # commit handling, could be message or commit info
212219 old_commit = None
@@ -219,6 +226,10 @@ def _from_line(cls, remote, line):
219226 flags |= cls .REMOTE_FAILURE
220227 elif "[no match]" in summary :
221228 flags |= cls .ERROR
229+ elif "[new tag]" in summary :
230+ flags |= cls .NEW_TAG
231+ elif "[new branch]" in summary :
232+ flags |= cls .NEW_HEAD
222233 # uptodate encoded in control character
223234 else :
224235 # fast-forward or forced update - was encoded in control character,
@@ -249,8 +260,9 @@ class FetchInfo(object):
249260 """
250261 __slots__ = ('ref' ,'commit_before_forced_update' , 'flags' , 'note' )
251262
252- HEAD_UPTODATE , REJECTED , FORCED_UPDATE , FAST_FORWARD , NEW_TAG , \
253- TAG_UPDATE , NEW_HEAD , ERROR = [ 1 << x for x in range (8 ) ]
263+ NEW_TAG , NEW_HEAD , HEAD_UPTODATE , TAG_UPDATE , REJECTED , FORCED_UPDATE , \
264+ FAST_FORWARD , ERROR = [ 1 << x for x in range (8 ) ]
265+
254266 # %c %-*s %-*s -> %s (%s)
255267 re_fetch_result = re .compile ("^\s*(.) (\[?[\w\s\.]+\]?)\s+(.+) -> ([/\w_\.-]+)( \(.*\)?$)?" )
256268
@@ -568,8 +580,20 @@ def _get_push_info(self, proc, progress):
568580 # END for each progress line
569581
570582 output = IterableList ('name' )
571- output .extend (PushInfo ._from_line (self , line ) for line in proc .stdout .readlines ())
572- proc .wait ()
583+ for line in proc .stdout .readlines ():
584+ try :
585+ output .append (PushInfo ._from_line (self , line ))
586+ except ValueError :
587+ # if an error happens, additional info is given which we cannot parse
588+ pass
589+ # END exception handling
590+ # END for each line
591+ try :
592+ proc .wait ()
593+ except GitCommandError :
594+ # if a push has rejected items, the command has non-zero return status
595+ pass
596+ # END exception handling
573597 return output
574598
575599
@@ -634,7 +658,11 @@ def push(self, refspec=None, progress=None, **kwargs):
634658 Returns
635659 IterableList(PushInfo, ...) iterable list of PushInfo instances, each
636660 one informing about an individual head which had been updated on the remote
637- side
661+ side.
662+ If the push contains rejected heads, these will have the PushInfo.ERROR bit set
663+ in their flags.
664+ If the operation fails completely, the length of the returned IterableList will
665+ be null.
638666 """
639667 proc = self .repo .git .push (self , refspec , porcelain = True , as_process = True , ** kwargs )
640668 return self ._get_push_info (proc , progress or PushProgress ())
0 commit comments