Skip to content

Commit 55eb3de

Browse files
committed
Added conditional usage of the --progress flag to all relevant methods, that is push, fetch, pull and clone. This allows progress information to be sent in newer git versions without breaking older ones (ideally)
1 parent 863b386 commit 55eb3de

File tree

3 files changed

+71
-53
lines changed

3 files changed

+71
-53
lines changed

‎git/remote.py

+60-9
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@
2424
TagReference
2525
)
2626

27-
from git.util import (
28-
join_path,
29-
_digest_process_messages,
30-
_finalize_proc
31-
)
27+
from git.util import join_path
3228
from gitdb.util import join
3329

3430
import re
@@ -37,6 +33,58 @@
3733

3834
__all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote')
3935

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+
4088

4189
class PushInfo(object):
4290
"""
@@ -445,7 +493,7 @@ def _get_fetch_info_from_stderr(self, proc, progress):
445493
# this also waits for the command to finish
446494
# Skip some progress lines that don't provide relevant information
447495
fetch_info_lines = list()
448-
for line in _digest_process_messages(proc.stderr, progress):
496+
for line in digest_process_messages(proc.stderr, progress):
449497
if line.startswith('From') or line.startswith('remote: Total'):
450498
continue
451499
elif line.startswith('warning:'):
@@ -467,15 +515,15 @@ def _get_fetch_info_from_stderr(self, proc, progress):
467515
output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
468516
for err_line,fetch_line in zip(fetch_info_lines, fetch_head_info))
469517

470-
_finalize_proc(proc)
518+
finalize_process(proc)
471519
return output
472520

473521
def _get_push_info(self, proc, progress):
474522
# read progress information from stderr
475523
# we hope stdout can hold all the data, it should ...
476524
# read the lines manually as it will use carriage returns between the messages
477525
# to override the previous one. This is why we read the bytes manually
478-
_digest_process_messages(proc.stderr, progress)
526+
digest_process_messages(proc.stderr, progress)
479527

480528
output = IterableList('name')
481529
for line in proc.stdout.readlines():
@@ -487,7 +535,7 @@ def _get_push_info(self, proc, progress):
487535
# END exception handling
488536
# END for each line
489537

490-
_finalize_proc(proc)
538+
finalize_process(proc)
491539
return output
492540

493541

@@ -514,6 +562,7 @@ def fetch(self, refspec=None, progress=None, **kwargs):
514562
:note:
515563
As fetch does not provide progress information to non-ttys, we cannot make
516564
it available here unfortunately as in the 'push' method."""
565+
kwargs = add_progress(kwargs, self.repo.git, progress)
517566
proc = self.repo.git.fetch(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs)
518567
return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress())
519568

@@ -525,6 +574,7 @@ def pull(self, refspec=None, progress=None, **kwargs):
525574
:param progress: see 'push' method
526575
:param kwargs: Additional arguments to be passed to git-pull
527576
:return: Please see 'fetch' method """
577+
kwargs = add_progress(kwargs, self.repo.git, progress)
528578
proc = self.repo.git.pull(self, refspec, with_extended_output=True, as_process=True, v=True, **kwargs)
529579
return self._get_fetch_info_from_stderr(proc, progress or RemoteProgress())
530580

@@ -546,6 +596,7 @@ def push(self, refspec=None, progress=None, **kwargs):
546596
in their flags.
547597
If the operation fails completely, the length of the returned IterableList will
548598
be null."""
599+
kwargs = add_progress(kwargs, self.repo.git, progress)
549600
proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True, **kwargs)
550601
return self._get_push_info(proc, progress or RemoteProgress())
551602

‎git/repo/base.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
from git.index import IndexFile
1212
from git.objects import *
1313
from git.config import GitConfigParser
14-
from git.remote import Remote
14+
from git.remote import (
15+
Remote,
16+
digest_process_messages,
17+
finalize_process,
18+
add_progress
19+
)
20+
1521
from git.db import (
1622
GitCmdObjectDB,
1723
GitDB
1824
)
1925

20-
21-
from git.util import (
22-
_digest_process_messages,
23-
_finalize_proc
24-
)
25-
2626
from gitdb.util import (
2727
join,
2828
isfile,
@@ -684,10 +684,11 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
684684
# END windows handling
685685

686686
try:
687-
proc = git.clone(url, path, with_extended_output=True, as_process=True, v=True, progress=True, **kwargs)
687+
proc = git.clone(url, path, with_extended_output=True, as_process=True, v=True, **add_progress(kwargs, git, progress))
688688
if progress:
689-
_digest_process_messages(proc.stderr, progress)
690-
_finalize_proc(proc)
689+
digest_process_messages(proc.stderr, progress)
690+
#END handle progress
691+
finalize_process(proc)
691692
finally:
692693
if prev_cwd is not None:
693694
os.chdir(prev_cwd)

‎git/util.py

-34
Original file line numberDiff line numberDiff line change
@@ -100,40 +100,6 @@ def get_user_id():
100100
# END get username from login
101101
return "%s@%s" % (username, platform.node())
102102

103-
def _digest_process_messages(fh, progress):
104-
"""Read progress messages from file-like object fh, supplying the respective
105-
progress messages to the progress instance.
106-
107-
:return: list(line, ...) list of lines without linebreaks that did
108-
not contain progress information"""
109-
line_so_far = ''
110-
dropped_lines = list()
111-
while True:
112-
char = fh.read(1)
113-
if not char:
114-
break
115-
116-
if char in ('\r', '\n'):
117-
dropped_lines.extend(progress._parse_progress_line(line_so_far))
118-
line_so_far = ''
119-
else:
120-
line_so_far += char
121-
# END process parsed line
122-
# END while file is not done reading
123-
return dropped_lines
124-
125-
def _finalize_proc(proc):
126-
"""Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
127-
try:
128-
proc.wait()
129-
except GitCommandError,e:
130-
# if a push has rejected items, the command has non-zero return status
131-
# a return status of 128 indicates a connection error - reraise the previous one
132-
if proc.poll() == 128:
133-
raise
134-
pass
135-
# END exception handling
136-
137103
#} END utilities
138104

139105
#{ Classes

0 commit comments

Comments
 (0)