Skip to content

Commit 7aba59a

Browse files
committed
Merge branch 'johnsca-sf-master' into 0.3
Merge all fixes from #134
2 parents 9c39afa + ff13922 commit 7aba59a

File tree

10 files changed

+62
-27
lines changed

10 files changed

+62
-27
lines changed

‎git/cmd.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def __del__(self):
8888
# try to kill it
8989
try:
9090
os.kill(self.proc.pid, 2) # interrupt signal
91+
self.proc.wait() # ensure process goes away
9192
exceptOSError:
9293
pass# ignore error when process already died
9394
exceptAttributeError:

‎git/objects/commit.py‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
Actor,
99
Iterable,
1010
Stats,
11+
finalize_process
1112
)
1213
fromgit.diffimportDiffable
1314
fromtreeimportTree
@@ -65,7 +66,6 @@ def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, aut
6566
message=None, parents=None, encoding=None, gpgsig=None):
6667
"""Instantiate a new Commit. All keyword arguments taking None as default will
6768
be implicitly set on first query.
68-
6969
:param binsha: 20 byte sha1
7070
:param parents: tuple( Commit, ... )
7171
is a tuple of commit ids or actual Commits
@@ -252,6 +252,10 @@ def _iter_from_process_or_stream(cls, repo, proc_or_stream):
252252
assertlen(hexsha) ==40, "Invalid line: %s"%hexsha
253253
yieldCommit(repo, hex_to_bin(hexsha))
254254
# END for each line in stream
255+
# TODO: Review this - it seems process handling got a bit out of control
256+
# due to many developers trying to fix the open file handles issue
257+
ifhasattr(proc_or_stream, 'wait'):
258+
finalize_process(proc_or_stream)
255259

256260

257261
@classmethod
@@ -430,14 +434,21 @@ def _deserialize(self, stream):
430434

431435
self.author, self.authored_date, self.author_tz_offset=parse_actor_and_date(next_line)
432436
self.committer, self.committed_date, self.committer_tz_offset=parse_actor_and_date(readline())
433-
437+
438+
# we might run into one or more mergetag blocks, skip those for now
439+
next_line=readline()
440+
whilenext_line.startswith('mergetag '):
441+
next_line=readline()
442+
whilenext_line.startswith(' '):
443+
next_line=readline()
434444

435445
# now we can have the encoding line, or an empty line followed by the optional
436446
# message.
437447
self.encoding=self.default_encoding
438448

439449
# read headers
440-
buf=readline().strip()
450+
enc=next_line
451+
buf=enc.strip()
441452
whilebuf!="":
442453
ifbuf[0:10] =="encoding ":
443454
self.encoding=buf[buf.find(' ')+1:]

‎git/objects/fun.py‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,13 @@ def tree_entries_from_data(data):
7070
# default encoding for strings in git is utf8
7171
# Only use the respective unicode object if the byte stream was encoded
7272
name=data[ns:i]
73-
name_enc=name.decode("utf-8")
74-
iflen(name) >len(name_enc):
75-
name=name_enc
73+
try:
74+
name_enc=name.decode("utf-8")
75+
exceptUnicodeDecodeError:
76+
pass
77+
else:
78+
iflen(name) >len(name_enc):
79+
name=name_enc
7680
# END handle encoding
7781

7882
# byte is NULL, get next 20
@@ -84,6 +88,7 @@ def tree_entries_from_data(data):
8488
returnout
8589

8690

91+
8792
def_find_by_name(tree_data, name, is_dir, start_at):
8893
"""return data entry matching the given name and tree mode
8994
or None.

‎git/objects/util.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,22 @@ def parse_date(string_date):
167167

168168
# precompiled regex
169169
_re_actor_epoch=re.compile(r'^.+? (.*) (\d+) ([+-]\d+).*$')
170+
_re_only_actor=re.compile(r'^.+? (.*)$')
170171

171172
defparse_actor_and_date(line):
172173
"""Parse out the actor (author or committer) info from a line like::
173174
174175
author Tom Preston-Werner <[email protected]> 1191999972 -0700
175176
176177
:return: [Actor, int_seconds_since_epoch, int_timezone_offset]"""
178+
actor, epoch, offset='', 0, 0
177179
m=_re_actor_epoch.search(line)
178-
actor, epoch, offset=m.groups()
180+
ifm:
181+
actor, epoch, offset=m.groups()
182+
else:
183+
m=_re_only_actor.search(line)
184+
actor=m.group(1) ifmelselineor''
179185
return (Actor._from_string(actor), int(epoch), utctz_to_altz(offset))
180-
181186

182187
#} END functions
183188

‎git/remote.py‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
TagReference
2525
)
2626

27-
fromgit.utilimportjoin_path
27+
fromgit.utilimport (
28+
join_path,
29+
finalize_process
30+
)
2831
fromgitdb.utilimportjoin
2932

3033
importre
@@ -58,18 +61,6 @@ def digest_process_messages(fh, progress):
5861
# END while file is not done reading
5962
returndropped_lines
6063

61-
deffinalize_process(proc):
62-
"""Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
63-
try:
64-
proc.wait()
65-
exceptGitCommandError,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-
ifproc.poll() ==128:
69-
raise
70-
pass
71-
# END exception handling
72-
7364
defadd_progress(kwargs, git, progress):
7465
"""Add the --progress flag to the given kwargs dict if supported by the
7566
git command. If the actual progress in the given progress instance is not

‎git/repo/base.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66

77
fromgit.excimportInvalidGitRepositoryError, NoSuchPathError
88
fromgit.cmdimportGit
9-
fromgit.utilimportActor
9+
fromgit.utilimport (
10+
Actor,
11+
finalize_process
12+
)
1013
fromgit.refsimport*
1114
fromgit.indeximportIndexFile
1215
fromgit.objectsimport*
1316
fromgit.configimportGitConfigParser
1417
fromgit.remoteimport (
1518
Remote,
1619
digest_process_messages,
17-
finalize_process,
1820
add_progress
1921
)
2022

@@ -540,6 +542,7 @@ def untracked_files(self):
540542
iffilename[0] ==filename[-1] =='"':
541543
filename=filename[1:-1].decode('string_escape')
542544
untracked_files.append(filename)
545+
finalize_process(proc)
543546
returnuntracked_files
544547

545548
@property

‎git/test/lib/helper.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class TestBase(TestCase):
227227
"""
228228

229229
@classmethod
230-
defsetUp(cls):
230+
defsetUpClass(cls):
231231
"""
232232
Dynamically add a read-only repository to our actual type. This way
233233
each test type has its own repository

‎git/test/test_fun.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
fromgit.objects.funimport (
33
traverse_tree_recursive,
44
traverse_trees_recursive,
5-
tree_to_stream
5+
tree_to_stream,
6+
tree_entries_from_data
67
)
78

89
fromgit.index.funimport (
@@ -249,3 +250,7 @@ def test_tree_traversal_single(self):
249250
entries=traverse_tree_recursive(odb, commit.tree.binsha, '')
250251
assertentries
251252
# END for each commit
253+
254+
deftest_tree_entries_from_data(self):
255+
r=tree_entries_from_data(b'100644 \x9f\0aaa')
256+
assertr== [('aaa', 33188, '\x9f')], r

‎git/test/test_git.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
classTestGit(TestBase):
1919

2020
@classmethod
21-
defsetUp(cls):
22-
super(TestGit, cls).setUp()
21+
defsetUpClass(cls):
22+
super(TestGit, cls).setUpClass()
2323
cls.git=Git(cls.rorepo.working_dir)
2424

2525
@patch.object(Git, 'execute')

‎git/util.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
# NOTE: Some of the unused imports might be used/imported by others.
1717
# Handle once test-cases are back up and running.
18+
fromexcimportGitCommandError
19+
1820
fromgitdb.utilimport (
1921
make_sha,
2022
LockedFD,
@@ -117,6 +119,18 @@ def get_user_id():
117119
""":return: string identifying the currently active system user as name@node"""
118120
return"%s@%s"% (getpass.getuser(), platform.node())
119121

122+
deffinalize_process(proc):
123+
"""Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
124+
try:
125+
proc.wait()
126+
exceptGitCommandError,e:
127+
# if a push has rejected items, the command has non-zero return status
128+
# a return status of 128 indicates a connection error - reraise the previous one
129+
ifproc.poll() ==128:
130+
raise
131+
pass
132+
# END exception handling
133+
120134
#} END utilities
121135

122136
#{Classes

0 commit comments

Comments
(0)