diff options
-rw-r--r-- | CONTRIBUTING.md | 6 | ||||
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | git/cmd.py | 13 | ||||
-rw-r--r-- | git/remote.py | 10 | ||||
-rw-r--r-- | git/repo/base.py | 3 | ||||
-rw-r--r-- | git/test/test_git.py | 1 | ||||
-rw-r--r-- | git/util.py | 18 |
7 files changed, 41 insertions, 17 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..421e59e9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,6 @@ +### How to contribute + +* [fork this project](https://github.com/gitpython-developers/GitPython/fork) on github +* Add yourself to AUTHORS.md and write your patch. **Write a test that fails unless your patch is present.** +* Initiate a pull request + @@ -45,11 +45,9 @@ Then run: tox -### SOURCE +### Contributions -GitPython's git repo is available on GitHub, which can be browsed at [github](https://github.com/gitpython-developers/GitPython) and cloned like that: - - git clone https://github.com/gitpython-developers/GitPython +Please have a look at the [contributions file][contributing]. ### Live Coding @@ -100,3 +98,4 @@ Now that there seems to be a massive user base, this should be motivation enough [twitch-channel]: http://www.twitch.tv/byronimo/profile [youtube-playlist]: https://www.youtube.com/playlist?list=PLMHbQxe1e9MnoEcLhn6Yhv5KAvpWkJbL0 +[contributing]: https://github.com/gitpython-developers/GitPython/blob/master/README.md
\ No newline at end of file @@ -14,7 +14,6 @@ import errno import mmap from git.odict import OrderedDict - from contextlib import contextmanager import signal from subprocess import ( @@ -36,6 +35,7 @@ from .exc import ( from git.compat import ( string_types, defenc, + force_bytes, PY3, bchr, # just to satisfy flake8 on py3 @@ -307,22 +307,27 @@ class Git(LazyMixin): def __getattr__(self, attr): return getattr(self.proc, attr) - def wait(self, stderr=None): + def wait(self, stderr=b''): """Wait for the process and return its status code. :param stderr: Previously read value of stderr, in case stderr is already closed. :warn: may deadlock if output or error pipes are used and not handled separately. :raise GitCommandError: if the return status is not 0""" + if stderr is None: + stderr = b'' + stderr = force_bytes(stderr) + status = self.proc.wait() def read_all_from_possibly_closed_stream(stream): try: - return stream.read() + return stderr + force_bytes(stream.read()) except ValueError: - return stderr or '' + return stderr or b'' if status != 0: errstr = read_all_from_possibly_closed_stream(self.proc.stderr) + log.debug('AutoInterrupt wait stderr: %r' % (errstr,)) raise GitCommandError(self.args, status, errstr) # END status handling return status diff --git a/git/remote.py b/git/remote.py index 42753977..e30debb7 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, @@ -570,11 +569,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: @@ -584,7 +583,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') diff --git a/git/repo/base.py b/git/repo/base.py index f43cc462..282dfc15 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -873,7 +873,8 @@ class Repo(object): @classmethod def _clone(cls, git, url, path, odb_default_type, progress, **kwargs): - progress = to_progress_instance(progress) + if progress is not None: + progress = to_progress_instance(progress) # special handling for windows for path at which the clone should be # created. diff --git a/git/test/test_git.py b/git/test/test_git.py index 2d6ca8bc..b46ac72d 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -210,7 +210,6 @@ class TestGit(TestBase): assert err.status == 128 else: assert 'FOO' in str(err) - assert err.status == 2 # end # end # end if select.poll exists diff --git a/git/util.py b/git/util.py index 5ed014fc..f5c69231 100644 --- a/git/util.py +++ b/git/util.py @@ -173,23 +173,35 @@ class RemoteProgress(object): DONE_TOKEN = 'done.' TOKEN_SEPARATOR = ', ' - __slots__ = ("_cur_line", "_seen_ops") + __slots__ = ("_cur_line", "_seen_ops", "_error_lines") re_op_absolute = re.compile(r"(remote: )?([\w\s]+):\s+()(\d+)()(.*)") re_op_relative = re.compile(r"(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)") def __init__(self): self._seen_ops = list() self._cur_line = None + self._error_lines = [] + + def error_lines(self): + """Returns all lines that started with error: or fatal:""" + return self._error_lines def _parse_progress_line(self, line): """Parse progress information from the given line as retrieved by git-push - or git-fetch + or git-fetch. + + Lines that seem to contain an error (i.e. start with error: or fatal:) are stored + separately and can be queried using `error_lines()`. :return: list(line, ...) list of lines that could not be processed""" # handle # Counting objects: 4, done. # Compressing objects: 50% (1/2) \rCompressing objects: 100% (2/2) \rCompressing objects: 100% (2/2), done. self._cur_line = line + if len(self._error_lines) > 0 or self._cur_line.startswith(('error:', 'fatal:')): + self._error_lines.append(self._cur_line) + return [] + sub_lines = line.split('\r') failed_lines = list() for sline in sub_lines: @@ -764,7 +776,7 @@ class WaitGroup(object): self.cv.notify_all() self.cv.release() - def wait(self): + def wait(self, stderr=b''): self.cv.acquire() while self.count > 0: self.cv.wait() |