Skip to content

Commit 4d67069

Browse files
committed
remote, gitpython-developers#525: pump fetch-infos instead of GIL-read stderr
1 parent c5027ae commit 4d67069

File tree

2 files changed

+23
-27
lines changed

2 files changed

+23
-27
lines changed

Diff for: git/remote.py

+10-17
Original file line numberDiff line numberDiff line change
@@ -630,25 +630,18 @@ def _get_fetch_info_from_stderr(self, proc, progress):
630630
cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())
631631

632632
progress_handler = progress.new_message_handler()
633+
handle_process_output(proc, None, progress_handler, finalize_process, decode_streams=False)
633634

634-
stderr_text = None
635-
636-
for line in proc.stderr:
635+
for line in progress.other_lines:
637636
line = force_text(line)
638-
for pline in progress_handler(line):
639-
# END handle special messages
640-
for cmd in cmds:
641-
if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
642-
fetch_info_lines.append(line)
643-
continue
644-
# end find command code
645-
# end for each comand code we know
646-
# end for each line progress didn't handle
647-
# end
648-
if progress.error_lines():
649-
stderr_text = '\n'.join(progress.error_lines())
650-
651-
finalize_process(proc, stderr=stderr_text)
637+
for cmd in cmds:
638+
if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
639+
fetch_info_lines.append(line)
640+
continue
641+
642+
if progress.error_lines:
643+
stderr_text = '\n'.join(progress.error_lines)
644+
log.warning("Received error messages while fetching: %s", stderr_text)
652645

653646
# read head information
654647
with open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') as fp:

Diff for: git/util.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -210,33 +210,34 @@ class RemoteProgress(object):
210210
DONE_TOKEN = 'done.'
211211
TOKEN_SEPARATOR = ', '
212212

213-
__slots__ = ("_cur_line", "_seen_ops", "_error_lines")
213+
__slots__ = ('_cur_line',
214+
'_seen_ops',
215+
'error_lines', # Lines that started with 'error:' or 'fatal:'.
216+
'other_lines') # Lines not denoting progress (i.e.g. push-infos).
214217
re_op_absolute = re.compile(r"(remote: )?([\w\s]+):\s+()(\d+)()(.*)")
215218
re_op_relative = re.compile(r"(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)")
216219

217220
def __init__(self):
218221
self._seen_ops = list()
219222
self._cur_line = None
220-
self._error_lines = []
221-
222-
def error_lines(self):
223-
"""Returns all lines that started with error: or fatal:"""
224-
return self._error_lines
223+
self.error_lines = []
224+
self.other_lines = []
225225

226226
def _parse_progress_line(self, line):
227227
"""Parse progress information from the given line as retrieved by git-push
228228
or git-fetch.
229229
230-
Lines that seem to contain an error (i.e. start with error: or fatal:) are stored
231-
separately and can be queried using `error_lines()`.
230+
- Lines that do not contain progress info are stored in :attr:`other_lines`.
231+
- Lines that seem to contain an error (i.e. start with error: or fatal:) are stored
232+
in :attr:`error_lines`.
232233
233234
:return: list(line, ...) list of lines that could not be processed"""
234235
# handle
235236
# Counting objects: 4, done.
236237
# Compressing objects: 50% (1/2) \rCompressing objects: 100% (2/2) \rCompressing objects: 100% (2/2), done.
237238
self._cur_line = line
238-
if len(self._error_lines) > 0 or self._cur_line.startswith(('error:', 'fatal:')):
239-
self._error_lines.append(self._cur_line)
239+
if len(self.error_lines) > 0 or self._cur_line.startswith(('error:', 'fatal:')):
240+
self.error_lines.append(self._cur_line)
240241
return []
241242

242243
sub_lines = line.split('\r')
@@ -295,6 +296,7 @@ def _parse_progress_line(self, line):
295296
self.line_dropped(sline)
296297
# Note: Don't add this line to the failed lines, as we have to silently
297298
# drop it
299+
self.other_lines.extend(failed_lines)
298300
return failed_lines
299301
# END handle op code
300302

@@ -320,6 +322,7 @@ def _parse_progress_line(self, line):
320322
max_count and float(max_count),
321323
message)
322324
# END for each sub line
325+
self.other_lines.extend(failed_lines)
323326
return failed_lines
324327

325328
def new_message_handler(self):

0 commit comments

Comments
 (0)