Skip to content

Commit feb1ea0

Browse files
committed
GitCmdStreamReader: fixed terrible bug which only kicked in if the stream was actually empty. This is a rare case that can happen during stream testing. Theoretically there shouldn't be any empty streams of course, but practically they do exist sometimes ;); fixed stream.seek implementation, which previously used seek on standard output
Improved GitCmd error handling
1 parent 55dcc17 commit feb1ea0

File tree

4 files changed

+23
-7
lines changed

4 files changed

+23
-7
lines changed

lib/git/cmd.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ def __init__(self, size, stream):
109109
self._size = size
110110
self._nbr = 0 # num bytes read
111111

112+
# special case: if the object is empty, has null bytes, get the
113+
# final newline right away.
114+
if size == 0:
115+
stream.read(1)
116+
# END handle empty streams
117+
112118
def read(self, size=-1):
113119
bytes_left = self._size - self._nbr
114120
if bytes_left == 0:
@@ -127,7 +133,6 @@ def read(self, size=-1):
127133
if self._size - self._nbr == 0:
128134
self._stream.read(1) # final newline
129135
# END finish reading
130-
131136
return data
132137

133138
def readline(self, size=-1):
@@ -146,7 +151,6 @@ def readline(self, size=-1):
146151
self._nbr += len(data)
147152

148153
# handle final byte
149-
# we inline everything, it must be fast !
150154
if self._size - self._nbr == 0:
151155
self._stream.read(1)
152156
# END finish reading
@@ -185,8 +189,9 @@ def next(self):
185189
def __del__(self):
186190
bytes_left = self._size - self._nbr
187191
if bytes_left:
188-
# seek and discard
189-
self._stream.seek(bytes_left + 1, os.SEEK_CUR) # includes terminating newline
192+
# read and discard - seeking is impossible within a stream
193+
# includes terminating newline
194+
self._stream.read(bytes_left + 1)
190195
# END handle incomplete read
191196

192197

@@ -454,7 +459,13 @@ def _parse_object_header(self, header_line):
454459
"""
455460
tokens = header_line.split()
456461
if len(tokens) != 3:
457-
raise ValueError("SHA named %s could not be resolved, git returned: %r" % (tokens[0], header_line.strip()) )
462+
if not tokens:
463+
raise ValueError("SHA could not be resolved, git returned: %r" % (header_line.strip()))
464+
else:
465+
raise ValueError("SHA %s could not be resolved, git returned: %r" % (tokens[0], header_line.strip()))
466+
# END handle actual return value
467+
# END error handling
468+
458469
if len(tokens[0]) != 40:
459470
raise ValueError("Failed to parse header: %r" % header_line)
460471
return (tokens[0], tokens[1], int(tokens[2]))

lib/git/objects/fun.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Module with functions which are supposed to be as fast as possible"""
22

3-
__all__ = ('tree_to_stream', 'tree_entries_from_data')
3+
__all__ = ('tree_to_stream', 'tree_entries_from_data', 'traverse_trees_recursive',
4+
'traverse_tree_recursive')
45

56
from stat import S_ISDIR
67

lib/git/repo.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def is_git_dir(d):
4242
os.readlink(headref).startswith('refs'))
4343
return False
4444

45+
4546
class Repo(object):
4647
"""
4748
Represents a git repository and allows you to query references,

test/testlib/helper.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,14 @@ def repo_creator(self):
109109
return func(self, rw_repo)
110110
except:
111111
print >> sys.stderr, "Keeping repo after failure: %s" % repo_dir
112+
repo_dir = None
112113
raise
113114
finally:
114115
os.chdir(prev_cwd)
115116
rw_repo.git.clear_cache()
116-
shutil.rmtree(repo_dir, onerror=_rmtree_onerror)
117+
if repo_dir is not None:
118+
shutil.rmtree(repo_dir, onerror=_rmtree_onerror)
119+
# END rm test repo if possible
117120
# END cleanup
118121
# END rw repo creator
119122
repo_creator.__name__ = func.__name__

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy