2424TagReference
2525)
2626
27- from git .util import join_path
27+ from git .util import join_path
2828from gitdb .util import join
2929
3030import re
3333
3434__all__ = ('RemoteProgress' ,'PushInfo' ,'FetchInfo' ,'Remote' )
3535
36+ #{ Utilities
37+
38+ def digest_process_messages (fh ,progress ):
39+ """Read progress messages from file-like object fh, supplying the respective
40+ progress messages to the progress instance.
41+
42+ :param fh: File handle to read from
43+ :return: list(line, ...) list of lines without linebreaks that did
44+ not contain progress information"""
45+ line_so_far = ''
46+ dropped_lines = list ()
47+ while True :
48+ char = fh .read (1 )
49+ if not char :
50+ break
51+
52+ if char in ('\r ' ,'\n ' ):
53+ dropped_lines .extend (progress ._parse_progress_line (line_so_far ))
54+ line_so_far = ''
55+ else :
56+ line_so_far += char
57+ # END process parsed line
58+ # END while file is not done reading
59+ return dropped_lines
60+
61+ def finalize_process (proc ):
62+ """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
63+ try :
64+ proc .wait ()
65+ except GitCommandError ,e :
66+ # if a push has rejected items, the command has non-zero return status
67+ # a return status of 128 indicates a connection error - reraise the previous one
68+ if proc .poll ()== 128 :
69+ raise
70+ pass
71+ # END exception handling
72+
73+ def add_progress (kwargs ,git ,progress ):
74+ """Add the --progress flag to the given kwargs dict if supported by the
75+ git command. If the actual progress in the given progress instance is not
76+ given, we do not request any progress
77+ :return: possibly altered kwargs"""
78+ if progress is not None :
79+ v = git .version_info
80+ if v [0 ]> 1 or v [1 ]> 7 or v [2 ]> 0 or v [3 ]> 3 :
81+ kwargs ['progress' ]= True
82+ #END handle --progress
83+ #END handle progress
84+ return kwargs
85+
86+ #} END utilities
87+
3688
3789class PushInfo (object ):
3890"""
@@ -432,42 +484,6 @@ def update(self, **kwargs):
432484self .repo .git .remote ("update" ,self .name )
433485return self
434486
435- def _digest_process_messages (self ,fh ,progress ):
436- """Read progress messages from file-like object fh, supplying the respective
437- progress messages to the progress instance.
438-
439- :return: list(line, ...) list of lines without linebreaks that did
440- not contain progress information"""
441- line_so_far = ''
442- dropped_lines = list ()
443- while True :
444- char = fh .read (1 )
445- if not char :
446- break
447-
448- if char in ('\r ' ,'\n ' ):
449- dropped_lines .extend (progress ._parse_progress_line (line_so_far ))
450- line_so_far = ''
451- else :
452- line_so_far += char
453- # END process parsed line
454- # END while file is not done reading
455- return dropped_lines
456-
457-
458- def _finalize_proc (self ,proc ):
459- """Wait for the process (fetch, pull or push) and handle its errors accordingly"""
460- try :
461- proc .wait ()
462- except GitCommandError ,e :
463- # if a push has rejected items, the command has non-zero return status
464- # a return status of 128 indicates a connection error - reraise the previous one
465- if proc .poll ()== 128 :
466- raise
467- pass
468- # END exception handling
469-
470-
471487def _get_fetch_info_from_stderr (self ,proc ,progress ):
472488# skip first line as it is some remote info we are not interested in
473489output = IterableList ('name' )
@@ -477,7 +493,7 @@ def _get_fetch_info_from_stderr(self, proc, progress):
477493# this also waits for the command to finish
478494# Skip some progress lines that don't provide relevant information
479495fetch_info_lines = list ()
480- for line in self . _digest_process_messages (proc .stderr ,progress ):
496+ for line in digest_process_messages (proc .stderr ,progress ):
481497if line .startswith ('From' )or line .startswith ('remote: Total' ):
482498continue
483499elif line .startswith ('warning:' ):
@@ -499,15 +515,15 @@ def _get_fetch_info_from_stderr(self, proc, progress):
499515output .extend (FetchInfo ._from_line (self .repo ,err_line ,fetch_line )
500516for err_line ,fetch_line in zip (fetch_info_lines ,fetch_head_info ))
501517
502- self . _finalize_proc (proc )
518+ finalize_process (proc )
503519return output
504520
505521def _get_push_info (self ,proc ,progress ):
506522# read progress information from stderr
507523# we hope stdout can hold all the data, it should ...
508524# read the lines manually as it will use carriage returns between the messages
509525# to override the previous one. This is why we read the bytes manually
510- self . _digest_process_messages (proc .stderr ,progress )
526+ digest_process_messages (proc .stderr ,progress )
511527
512528output = IterableList ('name' )
513529for line in proc .stdout .readlines ():
@@ -519,7 +535,7 @@ def _get_push_info(self, proc, progress):
519535# END exception handling
520536# END for each line
521537
522- self . _finalize_proc (proc )
538+ finalize_process (proc )
523539return output
524540
525541
@@ -546,6 +562,7 @@ def fetch(self, refspec=None, progress=None, **kwargs):
546562:note:
547563As fetch does not provide progress information to non-ttys, we cannot make
548564it available here unfortunately as in the 'push' method."""
565+ kwargs = add_progress (kwargs ,self .repo .git ,progress )
549566proc = self .repo .git .fetch (self ,refspec ,with_extended_output = True ,as_process = True ,v = True ,** kwargs )
550567return self ._get_fetch_info_from_stderr (proc ,progress or RemoteProgress ())
551568
@@ -557,6 +574,7 @@ def pull(self, refspec=None, progress=None, **kwargs):
557574:param progress: see 'push' method
558575:param kwargs: Additional arguments to be passed to git-pull
559576:return: Please see 'fetch' method """
577+ kwargs = add_progress (kwargs ,self .repo .git ,progress )
560578proc = self .repo .git .pull (self ,refspec ,with_extended_output = True ,as_process = True ,v = True ,** kwargs )
561579return self ._get_fetch_info_from_stderr (proc ,progress or RemoteProgress ())
562580
@@ -578,6 +596,7 @@ def push(self, refspec=None, progress=None, **kwargs):
578596in their flags.
579597If the operation fails completely, the length of the returned IterableList will
580598be null."""
599+ kwargs = add_progress (kwargs ,self .repo .git ,progress )
581600proc = self .repo .git .push (self ,refspec ,porcelain = True ,as_process = True ,** kwargs )
582601return self ._get_push_info (proc ,progress or RemoteProgress ())
583602