diff options
Diffstat (limited to 'git/remote.py')
| -rw-r--r-- | git/remote.py | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/git/remote.py b/git/remote.py index 5e9fe2c0..75a6875f 100644 --- a/git/remote.py +++ b/git/remote.py @@ -8,7 +8,6 @@ import re import os -from .exc import GitCommandError from .config import ( SectionConstraint, cp, @@ -24,7 +23,8 @@ from git.util import ( LazyMixin, Iterable, IterableList, - RemoteProgress + RemoteProgress, + CallableRemoteProgress ) from git.util import ( join_path, @@ -49,8 +49,8 @@ def add_progress(kwargs, git, progress): given, we do not request any progress :return: possibly altered kwargs""" if progress is not None: - v = git.version_info - if v[0] > 1 or v[1] > 7 or v[2] > 0 or v[3] > 3: + v = git.version_info[:2] + if v >= (1, 7): kwargs['progress'] = True # END handle --progress # END handle progress @@ -59,6 +59,23 @@ def add_progress(kwargs, git, progress): #} END utilities +def to_progress_instance(progress): + """Given the 'progress' return a suitable object derived from + RemoteProgress(). + """ + # new API only needs progress as a function + if callable(progress): + return CallableRemoteProgress(progress) + + # where None is passed create a parser that eats the progress + elif progress is None: + return RemoteProgress() + + # assume its the old API with an instance of RemoteProgress. + else: + return progress + + class PushInfo(object): """ @@ -186,7 +203,7 @@ class FetchInfo(object): NEW_TAG, NEW_HEAD, HEAD_UPTODATE, TAG_UPDATE, REJECTED, FORCED_UPDATE, \ FAST_FORWARD, ERROR = [1 << x for x in range(8)] - re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.$@]+\]?)\s+(.+) -> ([/\w_\+\.\-$@#]+)( \(.*\)?$)?") + re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.$@]+\]?)\s+(.+) -> ([/\w_\+\.\-$@#()]+)( \(.*\)?$)?") _flag_map = {'!': ERROR, '+': FORCED_UPDATE, @@ -585,6 +602,8 @@ class Remote(LazyMixin, Iterable): return self def _get_fetch_info_from_stderr(self, proc, progress): + progress = to_progress_instance(progress) + # skip first line as it is some remote info we are not interested in output = IterableList('name') @@ -598,11 +617,11 @@ class Remote(LazyMixin, Iterable): progress_handler = progress.new_message_handler() + stderr_text = None + for line in proc.stderr: line = force_text(line) for pline in progress_handler(line): - if line.startswith('fatal:') or line.startswith('error:'): - raise GitCommandError(("Error when fetching: %s" % line,), 2) # END handle special messages for cmd in cmds: if len(line) > 1 and line[0] == ' ' and line[1] == cmd: @@ -612,7 +631,10 @@ class Remote(LazyMixin, Iterable): # end for each comand code we know # end for each line progress didn't handle # end - finalize_process(proc) + if progress.error_lines(): + stderr_text = '\n'.join(progress.error_lines()) + + finalize_process(proc, stderr=stderr_text) # read head information fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') @@ -626,7 +648,7 @@ class Remote(LazyMixin, Iterable): msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n" msg += "Will ignore extra progress lines or fetch head lines." msg %= (l_fil, l_fhi) - log.warn(msg) + log.debug(msg) if l_fil < l_fhi: fetch_head_info = fetch_head_info[:l_fil] else: @@ -639,6 +661,8 @@ class Remote(LazyMixin, Iterable): return output def _get_push_info(self, proc, progress): + progress = to_progress_instance(progress) + # read progress information from stderr # we hope stdout can hold all the data, it should ... # read the lines manually as it will use carriage returns between the messages @@ -713,7 +737,7 @@ class Remote(LazyMixin, Iterable): proc = self.repo.git.fetch(self, *args, as_process=True, with_stdout=False, universal_newlines=True, v=True, **kwargs) - res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) + res = self._get_fetch_info_from_stderr(proc, progress) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() return res @@ -732,7 +756,7 @@ class Remote(LazyMixin, Iterable): kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.pull(self, refspec, with_stdout=False, as_process=True, universal_newlines=True, v=True, **kwargs) - res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress()) + res = self._get_fetch_info_from_stderr(proc, progress) if hasattr(self.repo.odb, 'update_cache'): self.repo.odb.update_cache() return res @@ -742,10 +766,19 @@ class Remote(LazyMixin, Iterable): :param refspec: see 'fetch' method :param progress: - Instance of type RemoteProgress allowing the caller to receive - progress information until the method returns. - If None, progress information will be discarded - + Can take one of many value types: + + * None to discard progress information + * A function (callable) that is called with the progress infomation. + + Signature: ``progress(op_code, cur_count, max_count=None, message='')``. + + `Click here <http://goo.gl/NPa7st>`_ for a description of all arguments + given to the function. + * An instance of a class derived from ``git.RemoteProgress`` that + overrides the ``update()`` function. + + :note: No further progress information is returned after push returns. :param kwargs: Additional arguments to be passed to git-push :return: IterableList(PushInfo, ...) iterable list of PushInfo instances, each @@ -758,7 +791,7 @@ class Remote(LazyMixin, Iterable): kwargs = add_progress(kwargs, self.repo.git, progress) proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True, universal_newlines=True, **kwargs) - return self._get_push_info(proc, progress or RemoteProgress()) + return self._get_push_info(proc, progress) @property def config_reader(self): |
