Skip to content

Commit ff13922

Browse files
committed
Merge branch 'sf-master' of https://github.com/johnsca/GitPython into johnsca-sf-master
Conflicts: git/cmd.py git/objects/commit.py git/objects/fun.py git/objects/util.py git/remote.py git/repo/base.py git/test/lib/helper.py git/test/test_commit.py git/test/test_fun.py git/util.py
2 parents 9c39afa + f7ed51b commit ff13922

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
except OSError:
9293
pass # ignore error when process already died
9394
except AttributeError:

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
from git.diff import Diffable
1314
from tree import Tree
@@ -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
assert len(hexsha) == 40, "Invalid line: %s" % hexsha
253253
yield Commit(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+
if hasattr(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+
while next_line.startswith('mergetag '):
441+
next_line = readline()
442+
while next_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
while buf != "":
442453
if buf[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-
if len(name) > len(name_enc):
75-
name = name_enc
73+
try:
74+
name_enc = name.decode("utf-8")
75+
except UnicodeDecodeError:
76+
pass
77+
else:
78+
if len(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
return out
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
def parse_actor_and_date(line):
172173
"""Parse out the actor (author or committer) info from a line like::
173174
174175
author Tom Preston-Werner <tom@mojombo.com> 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+
if m:
181+
actor, epoch, offset = m.groups()
182+
else:
183+
m = _re_only_actor.search(line)
184+
actor = m.group(1) if m else line or ''
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-
from git.util import join_path
27+
from git.util import (
28+
join_path,
29+
finalize_process
30+
)
2831
from gitdb.util import join
2932

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

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-
7364
def add_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
from git.exc import InvalidGitRepositoryError, NoSuchPathError
88
from git.cmd import Git
9-
from git.util import Actor
9+
from git.util import (
10+
Actor,
11+
finalize_process
12+
)
1013
from git.refs import *
1114
from git.index import IndexFile
1215
from git.objects import *
1316
from git.config import GitConfigParser
1417
from git.remote import (
1518
Remote,
1619
digest_process_messages,
17-
finalize_process,
1820
add_progress
1921
)
2022

@@ -540,6 +542,7 @@ def untracked_files(self):
540542
if filename[0] == filename[-1] == '"':
541543
filename = filename[1:-1].decode('string_escape')
542544
untracked_files.append(filename)
545+
finalize_process(proc)
543546
return untracked_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-
def setUp(cls):
230+
def setUpClass(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
from git.objects.fun import (
33
traverse_tree_recursive,
44
traverse_trees_recursive,
5-
tree_to_stream
5+
tree_to_stream,
6+
tree_entries_from_data
67
)
78

89
from git.index.fun import (
@@ -249,3 +250,7 @@ def test_tree_traversal_single(self):
249250
entries = traverse_tree_recursive(odb, commit.tree.binsha, '')
250251
assert entries
251252
# END for each commit
253+
254+
def test_tree_entries_from_data(self):
255+
r = tree_entries_from_data(b'100644 \x9f\0aaa')
256+
assert r == [('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
class TestGit(TestBase):
1919

2020
@classmethod
21-
def setUp(cls):
22-
super(TestGit, cls).setUp()
21+
def setUpClass(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+
from exc import GitCommandError
19+
1820
from gitdb.util import (
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+
def finalize_process(proc):
123+
"""Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
124+
try:
125+
proc.wait()
126+
except GitCommandError,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+
if proc.poll() == 128:
130+
raise
131+
pass
132+
# END exception handling
133+
120134
#} END utilities
121135

122136
#{ Classes

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