diff options
Diffstat (limited to 'git')
-rw-r--r-- | git/cmd.py | 1 | ||||
-rw-r--r-- | git/objects/commit.py | 17 | ||||
-rw-r--r-- | git/objects/fun.py | 11 | ||||
-rw-r--r-- | git/objects/util.py | 9 | ||||
-rw-r--r-- | git/remote.py | 17 | ||||
-rw-r--r-- | git/repo/base.py | 7 | ||||
-rw-r--r-- | git/test/lib/helper.py | 2 | ||||
-rw-r--r-- | git/test/test_fun.py | 7 | ||||
-rw-r--r-- | git/test/test_git.py | 4 | ||||
-rw-r--r-- | git/util.py | 14 |
10 files changed, 62 insertions, 27 deletions
@@ -88,6 +88,7 @@ class Git(LazyMixin): # try to kill it try: os.kill(self.proc.pid, 2) # interrupt signal + self.proc.wait() # ensure process goes away except OSError: pass # ignore error when process already died except AttributeError: diff --git a/git/objects/commit.py b/git/objects/commit.py index 4380f472..bc437e8b 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -8,6 +8,7 @@ from git.util import ( Actor, Iterable, Stats, + finalize_process ) from git.diff import Diffable from tree import Tree @@ -65,7 +66,6 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable): message=None, parents=None, encoding=None, gpgsig=None): """Instantiate a new Commit. All keyword arguments taking None as default will be implicitly set on first query. - :param binsha: 20 byte sha1 :param parents: tuple( Commit, ... ) is a tuple of commit ids or actual Commits @@ -252,6 +252,10 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable): assert len(hexsha) == 40, "Invalid line: %s" % hexsha yield Commit(repo, hex_to_bin(hexsha)) # END for each line in stream + # TODO: Review this - it seems process handling got a bit out of control + # due to many developers trying to fix the open file handles issue + if hasattr(proc_or_stream, 'wait'): + finalize_process(proc_or_stream) @classmethod @@ -430,14 +434,21 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable): self.author, self.authored_date, self.author_tz_offset = parse_actor_and_date(next_line) self.committer, self.committed_date, self.committer_tz_offset = parse_actor_and_date(readline()) - + + # we might run into one or more mergetag blocks, skip those for now + next_line = readline() + while next_line.startswith('mergetag '): + next_line = readline() + while next_line.startswith(' '): + next_line = readline() # now we can have the encoding line, or an empty line followed by the optional # message. self.encoding = self.default_encoding # read headers - buf = readline().strip() + enc = next_line + buf = enc.strip() while buf != "": if buf[0:10] == "encoding ": self.encoding = buf[buf.find(' ')+1:] diff --git a/git/objects/fun.py b/git/objects/fun.py index f73be542..66b7998e 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -70,9 +70,13 @@ def tree_entries_from_data(data): # default encoding for strings in git is utf8 # Only use the respective unicode object if the byte stream was encoded name = data[ns:i] - name_enc = name.decode("utf-8") - if len(name) > len(name_enc): - name = name_enc + try: + name_enc = name.decode("utf-8") + except UnicodeDecodeError: + pass + else: + if len(name) > len(name_enc): + name = name_enc # END handle encoding # byte is NULL, get next 20 @@ -84,6 +88,7 @@ def tree_entries_from_data(data): return out + def _find_by_name(tree_data, name, is_dir, start_at): """return data entry matching the given name and tree mode or None. diff --git a/git/objects/util.py b/git/objects/util.py index 2e44c9c0..cdf72bed 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -167,6 +167,7 @@ def parse_date(string_date): # precompiled regex _re_actor_epoch = re.compile(r'^.+? (.*) (\d+) ([+-]\d+).*$') +_re_only_actor = re.compile(r'^.+? (.*)$') def parse_actor_and_date(line): """Parse out the actor (author or committer) info from a line like:: @@ -174,10 +175,14 @@ def parse_actor_and_date(line): author Tom Preston-Werner <tom@mojombo.com> 1191999972 -0700 :return: [Actor, int_seconds_since_epoch, int_timezone_offset]""" + actor, epoch, offset = '', 0, 0 m = _re_actor_epoch.search(line) - actor, epoch, offset = m.groups() + if m: + actor, epoch, offset = m.groups() + else: + m = _re_only_actor.search(line) + actor = m.group(1) if m else line or '' return (Actor._from_string(actor), int(epoch), utctz_to_altz(offset)) - #} END functions diff --git a/git/remote.py b/git/remote.py index b06c0686..75e88e43 100644 --- a/git/remote.py +++ b/git/remote.py @@ -24,7 +24,10 @@ from refs import ( TagReference ) -from git.util import join_path +from git.util import ( + join_path, + finalize_process + ) from gitdb.util import join import re @@ -58,18 +61,6 @@ def digest_process_messages(fh, progress): # END while file is not done reading return dropped_lines -def finalize_process(proc): - """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly""" - try: - proc.wait() - except GitCommandError,e: - # if a push has rejected items, the command has non-zero return status - # a return status of 128 indicates a connection error - reraise the previous one - if proc.poll() == 128: - raise - pass - # END exception handling - def add_progress(kwargs, git, progress): """Add the --progress flag to the given kwargs dict if supported by the git command. If the actual progress in the given progress instance is not diff --git a/git/repo/base.py b/git/repo/base.py index 933c8c82..6a311f0b 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -6,7 +6,10 @@ from git.exc import InvalidGitRepositoryError, NoSuchPathError from git.cmd import Git -from git.util import Actor +from git.util import ( + Actor, + finalize_process + ) from git.refs import * from git.index import IndexFile from git.objects import * @@ -14,7 +17,6 @@ from git.config import GitConfigParser from git.remote import ( Remote, digest_process_messages, - finalize_process, add_progress ) @@ -540,6 +542,7 @@ class Repo(object): if filename[0] == filename[-1] == '"': filename = filename[1:-1].decode('string_escape') untracked_files.append(filename) + finalize_process(proc) return untracked_files @property diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 2634ecdb..a76f1a15 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -227,7 +227,7 @@ class TestBase(TestCase): """ @classmethod - def setUp(cls): + def setUpClass(cls): """ Dynamically add a read-only repository to our actual type. This way each test type has its own repository diff --git a/git/test/test_fun.py b/git/test/test_fun.py index 530988ef..096cd368 100644 --- a/git/test/test_fun.py +++ b/git/test/test_fun.py @@ -2,7 +2,8 @@ from git.test.lib import * from git.objects.fun import ( traverse_tree_recursive, traverse_trees_recursive, - tree_to_stream + tree_to_stream, + tree_entries_from_data ) from git.index.fun import ( @@ -249,3 +250,7 @@ class TestFun(TestBase): entries = traverse_tree_recursive(odb, commit.tree.binsha, '') assert entries # END for each commit + + def test_tree_entries_from_data(self): + r = tree_entries_from_data(b'100644 \x9f\0aaa') + assert r == [('aaa', 33188, '\x9f')], r diff --git a/git/test/test_git.py b/git/test/test_git.py index cdea1d3e..7132aa83 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -18,8 +18,8 @@ from git import ( Git, class TestGit(TestBase): @classmethod - def setUp(cls): - super(TestGit, cls).setUp() + def setUpClass(cls): + super(TestGit, cls).setUpClass() cls.git = Git(cls.rorepo.working_dir) @patch.object(Git, 'execute') diff --git a/git/util.py b/git/util.py index 30ccfa66..955d23de 100644 --- a/git/util.py +++ b/git/util.py @@ -15,6 +15,8 @@ import getpass # NOTE: Some of the unused imports might be used/imported by others. # Handle once test-cases are back up and running. +from exc import GitCommandError + from gitdb.util import ( make_sha, LockedFD, @@ -117,6 +119,18 @@ def get_user_id(): """:return: string identifying the currently active system user as name@node""" return "%s@%s" % (getpass.getuser(), platform.node()) +def finalize_process(proc): + """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly""" + try: + proc.wait() + except GitCommandError,e: + # if a push has rejected items, the command has non-zero return status + # a return status of 128 indicates a connection error - reraise the previous one + if proc.poll() == 128: + raise + pass + # END exception handling + #} END utilities #{ Classes |