@@ -204,8 +204,12 @@ class FetchInfo(object):
204204 # %c %-*s %-*s -> %s (%s)
205205 re_fetch_result = re .compile ("^\s*(.) (\[?[\w\s\.]+\]?)\s+(.+) -> ([/\w_\+\.\-#]+)( \(.*\)?$)?" )
206206
207- _flag_map = {'!' : ERROR , '+' : FORCED_UPDATE , '-' : TAG_UPDATE , '*' : 0 ,
208- '=' : HEAD_UPTODATE , ' ' : FAST_FORWARD }
207+ _flag_map = {'!' : ERROR ,
208+ '+' : FORCED_UPDATE ,
209+ '-' : TAG_UPDATE ,
210+ '*' : 0 ,
211+ '=' : HEAD_UPTODATE ,
212+ ' ' : FAST_FORWARD }
209213
210214 def __init__ (self , ref , flags , note = '' , old_commit = None ):
211215 """
@@ -259,19 +263,47 @@ def _from_line(cls, repo, line, fetch_line):
259263 except ValueError : # unpack error
260264 raise ValueError ("Failed to parse FETCH__HEAD line: %r" % fetch_line )
261265
266+ # parse flags from control_character
267+ flags = 0
268+ try :
269+ flags |= cls ._flag_map [control_character ]
270+ except KeyError :
271+ raise ValueError ("Control character %r unknown as parsed from line %r" % (control_character , line ))
272+ # END control char exception hanlding
273+
274+ # parse operation string for more info - makes no sense for symbolic refs, but we parse it anyway
275+ old_commit = None
276+ is_tag_operation = False
277+ if 'rejected' in operation :
278+ flags |= cls .REJECTED
279+ if 'new tag' in operation :
280+ flags |= cls .NEW_TAG
281+ is_tag_operation = True
282+ if 'tag update' in operation :
283+ flags |= cls .TAG_UPDATE
284+ is_tag_operation = True
285+ if 'new branch' in operation :
286+ flags |= cls .NEW_HEAD
287+ if '...' in operation or '..' in operation :
288+ split_token = '...'
289+ if control_character == ' ' :
290+ split_token = split_token [:- 1 ]
291+ old_commit = repo .rev_parse (operation .split (split_token )[0 ])
292+ # END handle refspec
293+
262294 # handle FETCH_HEAD and figure out ref type
263295 # If we do not specify a target branch like master:refs/remotes/origin/master,
264296 # the fetch result is stored in FETCH_HEAD which destroys the rule we usually
265297 # have. In that case we use a symbolic reference which is detached
266298 ref_type = None
267299 if remote_local_ref == "FETCH_HEAD" :
268300 ref_type = SymbolicReference
301+ elif ref_type_name == "tag" or is_tag_operation :
302+ ref_type = TagReference
269303 elif ref_type_name in ("remote-tracking" , "branch" ):
270304 # note: remote-tracking is just the first part of the 'remote-tracking branch' token.
271305 # We don't parse it correctly, but its enough to know what to do, and its new in git 1.7something
272306 ref_type = RemoteReference
273- elif ref_type_name == "tag" :
274- ref_type = TagReference
275307 else :
276308 raise TypeError ("Cannot handle reference type: %r" % ref_type_name )
277309 # END handle ref type
@@ -308,31 +340,6 @@ def _from_line(cls, repo, line, fetch_line):
308340
309341 note = (note and note .strip ()) or ''
310342
311- # parse flags from control_character
312- flags = 0
313- try :
314- flags |= cls ._flag_map [control_character ]
315- except KeyError :
316- raise ValueError ("Control character %r unknown as parsed from line %r" % (control_character , line ))
317- # END control char exception hanlding
318-
319- # parse operation string for more info - makes no sense for symbolic refs
320- old_commit = None
321- if isinstance (remote_local_ref , Reference ):
322- if 'rejected' in operation :
323- flags |= cls .REJECTED
324- if 'new tag' in operation :
325- flags |= cls .NEW_TAG
326- if 'new branch' in operation :
327- flags |= cls .NEW_HEAD
328- if '...' in operation or '..' in operation :
329- split_token = '...'
330- if control_character == ' ' :
331- split_token = split_token [:- 1 ]
332- old_commit = repo .rev_parse (operation .split (split_token )[0 ])
333- # END handle refspec
334- # END reference flag handling
335-
336343 return cls (remote_local_ref , flags , note , old_commit )
337344
338345
@@ -513,9 +520,17 @@ def _get_fetch_info_from_stderr(self, proc, progress):
513520 # this also waits for the command to finish
514521 # Skip some progress lines that don't provide relevant information
515522 fetch_info_lines = list ()
523+ # fetches all for later in case we don't get any ... this handling is a bit fishy as
524+ # the underlying logic of git is not properly understood. This fix merely helps a test-case, and probably
525+ # won't be too wrong otherwise.
526+ fetch_info_lines_reserve = list ()
516527 for line in digest_process_messages (proc .stderr , progress ):
528+ # cc, _, _ = line.split('\t', 3)
517529 if line .startswith ('From' ) or line .startswith ('remote: Total' ) or line .startswith ('POST' ) \
518530 or line .startswith (' =' ):
531+ # Why do we even skip lines that begin with a = ?
532+ if line .startswith (' =' ):
533+ fetch_info_lines_reserve .append (line )
519534 continue
520535 elif line .startswith ('warning:' ):
521536 print >> sys .stderr , line
@@ -536,9 +551,15 @@ def _get_fetch_info_from_stderr(self, proc, progress):
536551 # This project needs a lot of work !
537552 # assert len(fetch_info_lines) == len(fetch_head_info), "len(%s) != len(%s)" % (fetch_head_info, fetch_info_lines)
538553
554+ # EVIL HACK: This basically fixes our test-case, and possibly helps better results to be returned in future
555+ # The actual question is why we are unable to properly parse progress messages and sync them to the
556+ # respective fetch-head information ... .
557+ if len (fetch_info_lines ) != len (fetch_head_info ) and len (fetch_info_lines_reserve ) == len (fetch_head_info ):
558+ fetch_info_lines = fetch_info_lines_reserve
559+ # end
560+
539561 output .extend (FetchInfo ._from_line (self .repo , err_line , fetch_line )
540562 for err_line , fetch_line in zip (fetch_info_lines , fetch_head_info ))
541-
542563 finalize_process (proc )
543564 return output
544565
@@ -594,6 +615,7 @@ def fetch(self, refspec=None, progress=None, **kwargs):
594615 args = refspec
595616 else :
596617 args = [refspec ]
618+
597619 proc = self .repo .git .fetch (self , * args , with_extended_output = True , as_process = True , v = True , ** kwargs )
598620 return self ._get_fetch_info_from_stderr (proc , progress or RemoteProgress ())
599621
0 commit comments