summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md6
-rw-r--r--README.md7
-rw-r--r--git/cmd.py13
-rw-r--r--git/remote.py10
-rw-r--r--git/repo/base.py3
-rw-r--r--git/test/test_git.py1
-rw-r--r--git/util.py18
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
+
diff --git a/README.md b/README.md
index b3c5c947..7daa8317 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/git/cmd.py b/git/cmd.py
index a8afc144..82434673 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -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()