From cb68eef0865df6aedbc11cd81888625a70da6777 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 25 Nov 2010 17:01:25 +0100 Subject: Moved everything into the git subdirectory - some tests still need to be adjusted --- .gitmodules | 2 +- __init__.py | 48 - cmd.py | 515 ------- config.py | 420 ------ db.py | 61 - diff.py | 346 ----- exc.py | 58 - ext/gitdb | 1 - ez_setup.py | 222 ---- git/__init__.py | 48 + git/cmd.py | 515 +++++++ git/config.py | 420 ++++++ git/db.py | 61 + git/diff.py | 346 +++++ git/exc.py | 58 + git/ext/gitdb | 1 + git/ez_setup.py | 222 ++++ git/index/__init__.py | 4 + git/index/base.py | 1153 ++++++++++++++++ git/index/fun.py | 322 +++++ git/index/typ.py | 173 +++ git/index/util.py | 86 ++ git/objects/__init__.py | 21 + git/objects/base.py | 172 +++ git/objects/blob.py | 27 + git/objects/commit.py | 465 +++++++ git/objects/fun.py | 199 +++ git/objects/submodule/__init__.py | 2 + git/objects/submodule/base.py | 924 +++++++++++++ git/objects/submodule/root.py | 315 +++++ git/objects/submodule/util.py | 101 ++ git/objects/tag.py | 76 ++ git/objects/tree.py | 280 ++++ git/objects/util.py | 315 +++++ git/odict.py | 1399 ++++++++++++++++++++ git/refs/__init__.py | 21 + git/refs/head.py | 246 ++++ git/refs/log.py | 282 ++++ git/refs/reference.py | 84 ++ git/refs/remote.py | 63 + git/refs/symbolic.py | 618 +++++++++ git/refs/tag.py | 91 ++ git/remote.py | 603 +++++++++ git/repo/__init__.py | 3 + git/repo/base.py | 753 +++++++++++ git/repo/fun.py | 280 ++++ git/setup.py | 86 ++ git/test/__init__.py | 5 + git/test/fixtures/blame | 131 ++ git/test/fixtures/cat_file_blob | 1 + git/test/fixtures/cat_file_blob_nl | 1 + git/test/fixtures/cat_file_blob_size | 1 + git/test/fixtures/diff_2 | 54 + git/test/fixtures/diff_2f | 19 + git/test/fixtures/diff_f | 15 + git/test/fixtures/diff_i | 201 +++ git/test/fixtures/diff_mode_only | 1152 ++++++++++++++++ git/test/fixtures/diff_new_mode | 14 + git/test/fixtures/diff_numstat | 2 + git/test/fixtures/diff_p | 610 +++++++++ git/test/fixtures/diff_rename | 12 + git/test/fixtures/diff_tree_numstat_root | 3 + git/test/fixtures/for_each_ref_with_path_component | Bin 0 -> 84 bytes git/test/fixtures/git_config | 23 + git/test/fixtures/git_config_global | 24 + git/test/fixtures/index | Bin 0 -> 163616 bytes git/test/fixtures/index_merge | Bin 0 -> 9192 bytes git/test/fixtures/ls_tree_a | 7 + git/test/fixtures/ls_tree_b | 2 + git/test/fixtures/ls_tree_commit | 3 + git/test/fixtures/reflog_HEAD | 460 +++++++ git/test/fixtures/reflog_invalid_date | 2 + git/test/fixtures/reflog_invalid_email | 2 + git/test/fixtures/reflog_invalid_newsha | 2 + git/test/fixtures/reflog_invalid_oldsha | 2 + git/test/fixtures/reflog_invalid_sep | 2 + git/test/fixtures/reflog_master | 124 ++ git/test/fixtures/rev_list | 3 + git/test/fixtures/rev_list_bisect_all | 51 + git/test/fixtures/rev_list_commit_diffs | 8 + git/test/fixtures/rev_list_commit_idabbrev | 8 + git/test/fixtures/rev_list_commit_stats | 7 + git/test/fixtures/rev_list_count | 655 +++++++++ git/test/fixtures/rev_list_delta_a | 8 + git/test/fixtures/rev_list_delta_b | 11 + git/test/fixtures/rev_list_single | 7 + git/test/fixtures/rev_parse | 1 + git/test/fixtures/show_empty_commit | 6 + git/test/lib/__init__.py | 13 + git/test/lib/asserts.py | 50 + git/test/lib/helper.py | 245 ++++ git/test/performance/lib.py | 78 ++ git/test/performance/test_commit.py | 99 ++ git/test/performance/test_odb.py | 70 + git/test/performance/test_streams.py | 131 ++ git/test/performance/test_utils.py | 174 +++ git/test/test_actor.py | 36 + git/test/test_base.py | 100 ++ git/test/test_blob.py | 23 + git/test/test_commit.py | 275 ++++ git/test/test_config.py | 102 ++ git/test/test_db.py | 25 + git/test/test_diff.py | 108 ++ git/test/test_fun.py | 251 ++++ git/test/test_git.py | 84 ++ git/test/test_index.py | 669 ++++++++++ git/test/test_reflog.py | 102 ++ git/test/test_refs.py | 521 ++++++++ git/test/test_remote.py | 445 +++++++ git/test/test_repo.py | 604 +++++++++ git/test/test_stats.py | 25 + git/test/test_submodule.py | 546 ++++++++ git/test/test_tree.py | 144 ++ git/test/test_util.py | 109 ++ git/util.py | 602 +++++++++ index/__init__.py | 4 - index/base.py | 1153 ---------------- index/fun.py | 322 ----- index/typ.py | 173 --- index/util.py | 86 -- objects/__init__.py | 21 - objects/base.py | 172 --- objects/blob.py | 27 - objects/commit.py | 465 ------- objects/fun.py | 199 --- objects/submodule/__init__.py | 2 - objects/submodule/base.py | 924 ------------- objects/submodule/root.py | 315 ----- objects/submodule/util.py | 101 -- objects/tag.py | 76 -- objects/tree.py | 280 ---- objects/util.py | 315 ----- odict.py | 1399 -------------------- refs/__init__.py | 21 - refs/head.py | 246 ---- refs/log.py | 282 ---- refs/reference.py | 84 -- refs/remote.py | 63 - refs/symbolic.py | 618 --------- refs/tag.py | 91 -- remote.py | 603 --------- repo/__init__.py | 3 - repo/base.py | 753 ----------- repo/fun.py | 280 ---- setup.py | 86 -- test/__init__.py | 5 - test/fixtures/blame | 131 -- test/fixtures/cat_file_blob | 1 - test/fixtures/cat_file_blob_nl | 1 - test/fixtures/cat_file_blob_size | 1 - test/fixtures/diff_2 | 54 - test/fixtures/diff_2f | 19 - test/fixtures/diff_f | 15 - test/fixtures/diff_i | 201 --- test/fixtures/diff_mode_only | 1152 ---------------- test/fixtures/diff_new_mode | 14 - test/fixtures/diff_numstat | 2 - test/fixtures/diff_p | 610 --------- test/fixtures/diff_rename | 12 - test/fixtures/diff_tree_numstat_root | 3 - test/fixtures/for_each_ref_with_path_component | Bin 84 -> 0 bytes test/fixtures/git_config | 23 - test/fixtures/git_config_global | 24 - test/fixtures/index | Bin 163616 -> 0 bytes test/fixtures/index_merge | Bin 9192 -> 0 bytes test/fixtures/ls_tree_a | 7 - test/fixtures/ls_tree_b | 2 - test/fixtures/ls_tree_commit | 3 - test/fixtures/reflog_HEAD | 460 ------- test/fixtures/reflog_invalid_date | 2 - test/fixtures/reflog_invalid_email | 2 - test/fixtures/reflog_invalid_newsha | 2 - test/fixtures/reflog_invalid_oldsha | 2 - test/fixtures/reflog_invalid_sep | 2 - test/fixtures/reflog_master | 124 -- test/fixtures/rev_list | 3 - test/fixtures/rev_list_bisect_all | 51 - test/fixtures/rev_list_commit_diffs | 8 - test/fixtures/rev_list_commit_idabbrev | 8 - test/fixtures/rev_list_commit_stats | 7 - test/fixtures/rev_list_count | 655 --------- test/fixtures/rev_list_delta_a | 8 - test/fixtures/rev_list_delta_b | 11 - test/fixtures/rev_list_single | 7 - test/fixtures/rev_parse | 1 - test/fixtures/show_empty_commit | 6 - test/lib/__init__.py | 13 - test/lib/asserts.py | 50 - test/lib/helper.py | 245 ---- test/performance/lib.py | 78 -- test/performance/test_commit.py | 99 -- test/performance/test_odb.py | 70 - test/performance/test_streams.py | 131 -- test/performance/test_utils.py | 174 --- test/test_actor.py | 36 - test/test_base.py | 100 -- test/test_blob.py | 23 - test/test_commit.py | 275 ---- test/test_config.py | 102 -- test/test_db.py | 25 - test/test_diff.py | 108 -- test/test_fun.py | 251 ---- test/test_git.py | 84 -- test/test_index.py | 669 ---------- test/test_reflog.py | 102 -- test/test_refs.py | 521 -------- test/test_remote.py | 445 ------- test/test_repo.py | 604 --------- test/test_stats.py | 25 - test/test_submodule.py | 546 -------- test/test_tree.py | 144 -- test/test_util.py | 109 -- util.py | 602 --------- 213 files changed, 20106 insertions(+), 20106 deletions(-) delete mode 100644 __init__.py delete mode 100644 cmd.py delete mode 100644 config.py delete mode 100644 db.py delete mode 100644 diff.py delete mode 100644 exc.py delete mode 160000 ext/gitdb delete mode 100644 ez_setup.py create mode 100644 git/__init__.py create mode 100644 git/cmd.py create mode 100644 git/config.py create mode 100644 git/db.py create mode 100644 git/diff.py create mode 100644 git/exc.py create mode 160000 git/ext/gitdb create mode 100644 git/ez_setup.py create mode 100644 git/index/__init__.py create mode 100644 git/index/base.py create mode 100644 git/index/fun.py create mode 100644 git/index/typ.py create mode 100644 git/index/util.py create mode 100644 git/objects/__init__.py create mode 100644 git/objects/base.py create mode 100644 git/objects/blob.py create mode 100644 git/objects/commit.py create mode 100644 git/objects/fun.py create mode 100644 git/objects/submodule/__init__.py create mode 100644 git/objects/submodule/base.py create mode 100644 git/objects/submodule/root.py create mode 100644 git/objects/submodule/util.py create mode 100644 git/objects/tag.py create mode 100644 git/objects/tree.py create mode 100644 git/objects/util.py create mode 100644 git/odict.py create mode 100644 git/refs/__init__.py create mode 100644 git/refs/head.py create mode 100644 git/refs/log.py create mode 100644 git/refs/reference.py create mode 100644 git/refs/remote.py create mode 100644 git/refs/symbolic.py create mode 100644 git/refs/tag.py create mode 100644 git/remote.py create mode 100644 git/repo/__init__.py create mode 100644 git/repo/base.py create mode 100644 git/repo/fun.py create mode 100755 git/setup.py create mode 100644 git/test/__init__.py create mode 100644 git/test/fixtures/blame create mode 100644 git/test/fixtures/cat_file_blob create mode 100644 git/test/fixtures/cat_file_blob_nl create mode 100644 git/test/fixtures/cat_file_blob_size create mode 100644 git/test/fixtures/diff_2 create mode 100644 git/test/fixtures/diff_2f create mode 100644 git/test/fixtures/diff_f create mode 100644 git/test/fixtures/diff_i create mode 100755 git/test/fixtures/diff_mode_only create mode 100644 git/test/fixtures/diff_new_mode create mode 100644 git/test/fixtures/diff_numstat create mode 100644 git/test/fixtures/diff_p create mode 100644 git/test/fixtures/diff_rename create mode 100644 git/test/fixtures/diff_tree_numstat_root create mode 100644 git/test/fixtures/for_each_ref_with_path_component create mode 100644 git/test/fixtures/git_config create mode 100644 git/test/fixtures/git_config_global create mode 100644 git/test/fixtures/index create mode 100644 git/test/fixtures/index_merge create mode 100644 git/test/fixtures/ls_tree_a create mode 100644 git/test/fixtures/ls_tree_b create mode 100644 git/test/fixtures/ls_tree_commit create mode 100644 git/test/fixtures/reflog_HEAD create mode 100644 git/test/fixtures/reflog_invalid_date create mode 100644 git/test/fixtures/reflog_invalid_email create mode 100644 git/test/fixtures/reflog_invalid_newsha create mode 100644 git/test/fixtures/reflog_invalid_oldsha create mode 100644 git/test/fixtures/reflog_invalid_sep create mode 100644 git/test/fixtures/reflog_master create mode 100644 git/test/fixtures/rev_list create mode 100644 git/test/fixtures/rev_list_bisect_all create mode 100644 git/test/fixtures/rev_list_commit_diffs create mode 100644 git/test/fixtures/rev_list_commit_idabbrev create mode 100644 git/test/fixtures/rev_list_commit_stats create mode 100644 git/test/fixtures/rev_list_count create mode 100644 git/test/fixtures/rev_list_delta_a create mode 100644 git/test/fixtures/rev_list_delta_b create mode 100644 git/test/fixtures/rev_list_single create mode 100644 git/test/fixtures/rev_parse create mode 100644 git/test/fixtures/show_empty_commit create mode 100644 git/test/lib/__init__.py create mode 100644 git/test/lib/asserts.py create mode 100644 git/test/lib/helper.py create mode 100644 git/test/performance/lib.py create mode 100644 git/test/performance/test_commit.py create mode 100644 git/test/performance/test_odb.py create mode 100644 git/test/performance/test_streams.py create mode 100644 git/test/performance/test_utils.py create mode 100644 git/test/test_actor.py create mode 100644 git/test/test_base.py create mode 100644 git/test/test_blob.py create mode 100644 git/test/test_commit.py create mode 100644 git/test/test_config.py create mode 100644 git/test/test_db.py create mode 100644 git/test/test_diff.py create mode 100644 git/test/test_fun.py create mode 100644 git/test/test_git.py create mode 100644 git/test/test_index.py create mode 100644 git/test/test_reflog.py create mode 100644 git/test/test_refs.py create mode 100644 git/test/test_remote.py create mode 100644 git/test/test_repo.py create mode 100644 git/test/test_stats.py create mode 100644 git/test/test_submodule.py create mode 100644 git/test/test_tree.py create mode 100644 git/test/test_util.py create mode 100644 git/util.py delete mode 100644 index/__init__.py delete mode 100644 index/base.py delete mode 100644 index/fun.py delete mode 100644 index/typ.py delete mode 100644 index/util.py delete mode 100644 objects/__init__.py delete mode 100644 objects/base.py delete mode 100644 objects/blob.py delete mode 100644 objects/commit.py delete mode 100644 objects/fun.py delete mode 100644 objects/submodule/__init__.py delete mode 100644 objects/submodule/base.py delete mode 100644 objects/submodule/root.py delete mode 100644 objects/submodule/util.py delete mode 100644 objects/tag.py delete mode 100644 objects/tree.py delete mode 100644 objects/util.py delete mode 100644 odict.py delete mode 100644 refs/__init__.py delete mode 100644 refs/head.py delete mode 100644 refs/log.py delete mode 100644 refs/reference.py delete mode 100644 refs/remote.py delete mode 100644 refs/symbolic.py delete mode 100644 refs/tag.py delete mode 100644 remote.py delete mode 100644 repo/__init__.py delete mode 100644 repo/base.py delete mode 100644 repo/fun.py delete mode 100755 setup.py delete mode 100644 test/__init__.py delete mode 100644 test/fixtures/blame delete mode 100644 test/fixtures/cat_file_blob delete mode 100644 test/fixtures/cat_file_blob_nl delete mode 100644 test/fixtures/cat_file_blob_size delete mode 100644 test/fixtures/diff_2 delete mode 100644 test/fixtures/diff_2f delete mode 100644 test/fixtures/diff_f delete mode 100644 test/fixtures/diff_i delete mode 100755 test/fixtures/diff_mode_only delete mode 100644 test/fixtures/diff_new_mode delete mode 100644 test/fixtures/diff_numstat delete mode 100644 test/fixtures/diff_p delete mode 100644 test/fixtures/diff_rename delete mode 100644 test/fixtures/diff_tree_numstat_root delete mode 100644 test/fixtures/for_each_ref_with_path_component delete mode 100644 test/fixtures/git_config delete mode 100644 test/fixtures/git_config_global delete mode 100644 test/fixtures/index delete mode 100644 test/fixtures/index_merge delete mode 100644 test/fixtures/ls_tree_a delete mode 100644 test/fixtures/ls_tree_b delete mode 100644 test/fixtures/ls_tree_commit delete mode 100644 test/fixtures/reflog_HEAD delete mode 100644 test/fixtures/reflog_invalid_date delete mode 100644 test/fixtures/reflog_invalid_email delete mode 100644 test/fixtures/reflog_invalid_newsha delete mode 100644 test/fixtures/reflog_invalid_oldsha delete mode 100644 test/fixtures/reflog_invalid_sep delete mode 100644 test/fixtures/reflog_master delete mode 100644 test/fixtures/rev_list delete mode 100644 test/fixtures/rev_list_bisect_all delete mode 100644 test/fixtures/rev_list_commit_diffs delete mode 100644 test/fixtures/rev_list_commit_idabbrev delete mode 100644 test/fixtures/rev_list_commit_stats delete mode 100644 test/fixtures/rev_list_count delete mode 100644 test/fixtures/rev_list_delta_a delete mode 100644 test/fixtures/rev_list_delta_b delete mode 100644 test/fixtures/rev_list_single delete mode 100644 test/fixtures/rev_parse delete mode 100644 test/fixtures/show_empty_commit delete mode 100644 test/lib/__init__.py delete mode 100644 test/lib/asserts.py delete mode 100644 test/lib/helper.py delete mode 100644 test/performance/lib.py delete mode 100644 test/performance/test_commit.py delete mode 100644 test/performance/test_odb.py delete mode 100644 test/performance/test_streams.py delete mode 100644 test/performance/test_utils.py delete mode 100644 test/test_actor.py delete mode 100644 test/test_base.py delete mode 100644 test/test_blob.py delete mode 100644 test/test_commit.py delete mode 100644 test/test_config.py delete mode 100644 test/test_db.py delete mode 100644 test/test_diff.py delete mode 100644 test/test_fun.py delete mode 100644 test/test_git.py delete mode 100644 test/test_index.py delete mode 100644 test/test_reflog.py delete mode 100644 test/test_refs.py delete mode 100644 test/test_remote.py delete mode 100644 test/test_repo.py delete mode 100644 test/test_stats.py delete mode 100644 test/test_submodule.py delete mode 100644 test/test_tree.py delete mode 100644 test/test_util.py delete mode 100644 util.py diff --git a/.gitmodules b/.gitmodules index 70a60616..2fb04c9a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "gitdb"] - path = ext/gitdb + path = git/ext/gitdb url = git://gitorious.org/git-python/gitdb.git diff --git a/__init__.py b/__init__.py deleted file mode 100644 index 483ac091..00000000 --- a/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -# __init__.py -# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors -# -# This module is part of GitPython and is released under -# the BSD License: http://www.opensource.org/licenses/bsd-license.php - -import os -import sys -import inspect - -__version__ = 'git' - - -#{ Initialization -def _init_externals(): - """Initialize external projects by putting them into the path""" - sys.path.append(os.path.join(os.path.dirname(__file__), 'ext')) - -#} END initialization - -################# -_init_externals() -################# - -#{ Imports - -from git.config import GitConfigParser -from git.objects import * -from git.refs import * -from git.diff import * -from git.exc import * -from git.db import * -from git.cmd import Git -from git.repo import Repo -from git.remote import * -from git.index import * -from git.util import ( - LockFile, - BlockingLockFile, - Stats, - Actor - ) - -#} END imports - -__all__ = [ name for name, obj in locals().items() - if not (name.startswith('_') or inspect.ismodule(obj)) ] - diff --git a/cmd.py b/cmd.py deleted file mode 100644 index 60887f5d..00000000 --- a/cmd.py +++ /dev/null @@ -1,515 +0,0 @@ -# cmd.py -# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors -# -# This module is part of GitPython and is released under -# the BSD License: http://www.opensource.org/licenses/bsd-license.php - -import os, sys -from util import * -from exc import GitCommandError - -from subprocess import ( - call, - Popen, - PIPE - ) - -# Enables debugging of GitPython's git commands -GIT_PYTHON_TRACE = os.environ.get("GIT_PYTHON_TRACE", False) - -execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output', - 'with_exceptions', 'as_process', - 'output_stream' ) - -__all__ = ('Git', ) - -def dashify(string): - return string.replace('_', '-') - -class Git(object): - """ - The Git class manages communication with the Git binary. - - It provides a convenient interface to calling the Git binary, such as in:: - - g = Git( git_dir ) - g.init() # calls 'git init' program - rval = g.ls_files() # calls 'git ls-files' program - - ``Debugging`` - Set the GIT_PYTHON_TRACE environment variable print each invocation - of the command to stdout. - Set its value to 'full' to see details about the returned values. - """ - __slots__ = ("_working_dir", "cat_file_all", "cat_file_header") - - # CONFIGURATION - # The size in bytes read from stdout when copying git's output to another stream - max_chunk_size = 1024*64 - - class AutoInterrupt(object): - """Kill/Interrupt the stored process instance once this instance goes out of scope. It is - used to prevent processes piling up in case iterators stop reading. - Besides all attributes are wired through to the contained process object. - - The wait method was overridden to perform automatic status code checking - and possibly raise.""" - __slots__= ("proc", "args") - - def __init__(self, proc, args ): - self.proc = proc - self.args = args - - def __del__(self): - # did the process finish already so we have a return code ? - if self.proc.poll() is not None: - return - - # can be that nothing really exists anymore ... - if os is None: - return - - # try to kill it - try: - os.kill(self.proc.pid, 2) # interrupt signal - except AttributeError: - # try windows - # for some reason, providing None for stdout/stderr still prints something. This is why - # we simply use the shell and redirect to nul. Its slower than CreateProcess, question - # is whether we really want to see all these messages. Its annoying no matter what. - call(("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(self.proc.pid)), shell=True) - # END exception handling - - def __getattr__(self, attr): - return getattr(self.proc, attr) - - def wait(self): - """Wait for the process and return its status code. - - :raise GitCommandError: if the return status is not 0""" - status = self.proc.wait() - if status != 0: - raise GitCommandError(self.args, status, self.proc.stderr.read()) - # END status handling - return status - # END auto interrupt - - class CatFileContentStream(object): - """Object representing a sized read-only stream returning the contents of - an object. - It behaves like a stream, but counts the data read and simulates an empty - stream once our sized content region is empty. - If not all data is read to the end of the objects's lifetime, we read the - rest to assure the underlying stream continues to work""" - - __slots__ = ('_stream', '_nbr', '_size') - - def __init__(self, size, stream): - self._stream = stream - self._size = size - self._nbr = 0 # num bytes read - - # special case: if the object is empty, has null bytes, get the - # final newline right away. - if size == 0: - stream.read(1) - # END handle empty streams - - def read(self, size=-1): - bytes_left = self._size - self._nbr - if bytes_left == 0: - return '' - if size > -1: - # assure we don't try to read past our limit - size = min(bytes_left, size) - else: - # they try to read all, make sure its not more than what remains - size = bytes_left - # END check early depletion - data = self._stream.read(size) - self._nbr += len(data) - - # check for depletion, read our final byte to make the stream usable by others - if self._size - self._nbr == 0: - self._stream.read(1) # final newline - # END finish reading - return data - - def readline(self, size=-1): - if self._nbr == self._size: - return '' - - # clamp size to lowest allowed value - bytes_left = self._size - self._nbr - if size > -1: - size = min(bytes_left, size) - else: - size = bytes_left - # END handle size - - data = self._stream.readline(size) - self._nbr += len(data) - - # handle final byte - if self._size - self._nbr == 0: - self._stream.read(1) - # END finish reading - - return data - - def readlines(self, size=-1): - if self._nbr == self._size: - return list() - - # leave all additional logic to our readline method, we just check the size - out = list() - nbr = 0 - while True: - line = self.readline() - if not line: - break - out.append(line) - if size > -1: - nbr += len(line) - if nbr > size: - break - # END handle size constraint - # END readline loop - return out - - def __iter__(self): - return self - - def next(self): - line = self.readline() - if not line: - raise StopIteration - return line - - def __del__(self): - bytes_left = self._size - self._nbr - if bytes_left: - # read and discard - seeking is impossible within a stream - # includes terminating newline - self._stream.read(bytes_left + 1) - # END handle incomplete read - - - def __init__(self, working_dir=None): - """Initialize this instance with: - - :param working_dir: - Git directory we should work in. If None, we always work in the current - directory as returned by os.getcwd(). - It is meant to be the working tree directory if available, or the - .git directory in case of bare repositories.""" - super(Git, self).__init__() - self._working_dir = working_dir - - # cached command slots - self.cat_file_header = None - self.cat_file_all = None - - def __getattr__(self, name): - """A convenience method as it allows to call the command as if it was - an object. - :return: Callable object that will execute call _call_process with your arguments.""" - if name[:1] == '_': - raise AttributeError(name) - return lambda *args, **kwargs: self._call_process(name, *args, **kwargs) - - @property - def working_dir(self): - """:return: Git directory we are working on""" - return self._working_dir - - def execute(self, command, - istream=None, - with_keep_cwd=False, - with_extended_output=False, - with_exceptions=True, - as_process=False, - output_stream=None, - **subprocess_kwargs - ): - """Handles executing the command on the shell and consumes and returns - the returned information (stdout) - - :param command: - The command argument list to execute. - It should be a string, or a sequence of program arguments. The - program to execute is the first item in the args sequence or string. - - :param istream: - Standard input filehandle passed to subprocess.Popen. - - :param with_keep_cwd: - Whether to use the current working directory from os.getcwd(). - The cmd otherwise uses its own working_dir that it has been initialized - with if possible. - - :param with_extended_output: - Whether to return a (status, stdout, stderr) tuple. - - :param with_exceptions: - Whether to raise an exception when git returns a non-zero status. - - :param as_process: - Whether to return the created process instance directly from which - streams can be read on demand. This will render with_extended_output and - with_exceptions ineffective - the caller will have - to deal with the details himself. - It is important to note that the process will be placed into an AutoInterrupt - wrapper that will interrupt the process once it goes out of scope. If you - use the command in iterators, you should pass the whole process instance - instead of a single stream. - - :param output_stream: - If set to a file-like object, data produced by the git command will be - output to the given stream directly. - This feature only has any effect if as_process is False. Processes will - always be created with a pipe due to issues with subprocess. - This merely is a workaround as data will be copied from the - output pipe to the given output stream directly. - - :param subprocess_kwargs: - Keyword arguments to be passed to subprocess.Popen. Please note that - some of the valid kwargs are already set by this method, the ones you - specify may not be the same ones. - - :return: - * str(output) if extended_output = False (Default) - * tuple(int(status), str(stdout), str(stderr)) if extended_output = True - - if ouput_stream is True, the stdout value will be your output stream: - * output_stream if extended_output = False - * tuple(int(status), output_stream, str(stderr)) if extended_output = True - - :raise GitCommandError: - - :note: - If you add additional keyword arguments to the signature of this method, - you must update the execute_kwargs tuple housed in this module.""" - if GIT_PYTHON_TRACE and not GIT_PYTHON_TRACE == 'full': - print ' '.join(command) - - # Allow the user to have the command executed in their working dir. - if with_keep_cwd or self._working_dir is None: - cwd = os.getcwd() - else: - cwd=self._working_dir - - # Start the process - proc = Popen(command, - cwd=cwd, - stdin=istream, - stderr=PIPE, - stdout=PIPE, - close_fds=(os.name=='posix'),# unsupported on linux - **subprocess_kwargs - ) - if as_process: - return self.AutoInterrupt(proc, command) - - # Wait for the process to return - status = 0 - stdout_value = '' - stderr_value = '' - try: - if output_stream is None: - stdout_value, stderr_value = proc.communicate() - # strip trailing "\n" - if stdout_value.endswith("\n"): - stdout_value = stdout_value[:-1] - if stderr_value.endswith("\n"): - stderr_value = stderr_value[:-1] - status = proc.returncode - else: - stream_copy(proc.stdout, output_stream, self.max_chunk_size) - stdout_value = output_stream - stderr_value = proc.stderr.read() - # strip trailing "\n" - if stderr_value.endswith("\n"): - stderr_value = stderr_value[:-1] - status = proc.wait() - # END stdout handling - finally: - proc.stdout.close() - proc.stderr.close() - - if GIT_PYTHON_TRACE == 'full': - cmdstr = " ".join(command) - if stderr_value: - print "%s -> %d; stdout: '%s'; stderr: '%s'" % (cmdstr, status, stdout_value, stderr_value) - elif stdout_value: - print "%s -> %d; stdout: '%s'" % (cmdstr, status, stdout_value) - else: - print "%s -> %d" % (cmdstr, status) - # END handle debug printing - - if with_exceptions and status != 0: - raise GitCommandError(command, status, stderr_value) - - # Allow access to the command's status code - if with_extended_output: - return (status, stdout_value, stderr_value) - else: - return stdout_value - - def transform_kwargs(self, **kwargs): - """Transforms Python style kwargs into git command line options.""" - args = list() - for k, v in kwargs.items(): - if len(k) == 1: - if v is True: - args.append("-%s" % k) - elif type(v) is not bool: - args.append("-%s%s" % (k, v)) - else: - if v is True: - args.append("--%s" % dashify(k)) - elif type(v) is not bool: - args.append("--%s=%s" % (dashify(k), v)) - return args - - @classmethod - def __unpack_args(cls, arg_list): - if not isinstance(arg_list, (list,tuple)): - return [ str(arg_list) ] - - outlist = list() - for arg in arg_list: - if isinstance(arg_list, (list, tuple)): - outlist.extend(cls.__unpack_args( arg )) - # END recursion - else: - outlist.append(str(arg)) - # END for each arg - return outlist - - def _call_process(self, method, *args, **kwargs): - """Run the given git command with the specified arguments and return - the result as a String - - :param method: - is the command. Contained "_" characters will be converted to dashes, - such as in 'ls_files' to call 'ls-files'. - - :param args: - is the list of arguments. If None is included, it will be pruned. - This allows your commands to call git more conveniently as None - is realized as non-existent - - :param kwargs: - is a dict of keyword arguments. - This function accepts the same optional keyword arguments - as execute(). - - ``Examples``:: - git.rev_list('master', max_count=10, header=True) - - :return: Same as ``execute``""" - # Handle optional arguments prior to calling transform_kwargs - # otherwise these'll end up in args, which is bad. - _kwargs = dict() - for kwarg in execute_kwargs: - try: - _kwargs[kwarg] = kwargs.pop(kwarg) - except KeyError: - pass - - # Prepare the argument list - opt_args = self.transform_kwargs(**kwargs) - - ext_args = self.__unpack_args([a for a in args if a is not None]) - args = opt_args + ext_args - - call = ["git", dashify(method)] - call.extend(args) - - return self.execute(call, **_kwargs) - - def _parse_object_header(self, header_line): - """ - :param header_line: - type_string size_as_int - - :return: (hex_sha, type_string, size_as_int) - - :raise ValueError: if the header contains indication for an error due to - incorrect input sha""" - tokens = header_line.split() - if len(tokens) != 3: - if not tokens: - raise ValueError("SHA could not be resolved, git returned: %r" % (header_line.strip())) - else: - raise ValueError("SHA %s could not be resolved, git returned: %r" % (tokens[0], header_line.strip())) - # END handle actual return value - # END error handling - - if len(tokens[0]) != 40: - raise ValueError("Failed to parse header: %r" % header_line) - return (tokens[0], tokens[1], int(tokens[2])) - - def __prepare_ref(self, ref): - # required for command to separate refs on stdin - refstr = str(ref) # could be ref-object - if refstr.endswith("\n"): - return refstr - return refstr + "\n" - - def __get_persistent_cmd(self, attr_name, cmd_name, *args,**kwargs): - cur_val = getattr(self, attr_name) - if cur_val is not None: - return cur_val - - options = { "istream" : PIPE, "as_process" : True } - options.update( kwargs ) - - cmd = self._call_process( cmd_name, *args, **options ) - setattr(self, attr_name, cmd ) - return cmd - - def __get_object_header(self, cmd, ref): - cmd.stdin.write(self.__prepare_ref(ref)) - cmd.stdin.flush() - return self._parse_object_header(cmd.stdout.readline()) - - def get_object_header(self, ref): - """ Use this method to quickly examine the type and size of the object behind - the given ref. - - :note: The method will only suffer from the costs of command invocation - once and reuses the command in subsequent calls. - - :return: (hexsha, type_string, size_as_int)""" - cmd = self.__get_persistent_cmd("cat_file_header", "cat_file", batch_check=True) - return self.__get_object_header(cmd, ref) - - def get_object_data(self, ref): - """ As get_object_header, but returns object data as well - :return: (hexsha, type_string, size_as_int,data_string) - :note: not threadsafe""" - hexsha, typename, size, stream = self.stream_object_data(ref) - data = stream.read(size) - del(stream) - return (hexsha, typename, size, data) - - def stream_object_data(self, ref): - """As get_object_header, but returns the data as a stream - :return: (hexsha, type_string, size_as_int, stream) - :note: This method is not threadsafe, you need one independent Command instance - per thread to be safe !""" - cmd = self.__get_persistent_cmd("cat_file_all", "cat_file", batch=True) - hexsha, typename, size = self.__get_object_header(cmd, ref) - return (hexsha, typename, size, self.CatFileContentStream(size, cmd.stdout)) - - def clear_cache(self): - """Clear all kinds of internal caches to release resources. - - Currently persistent commands will be interrupted. - - :return: self""" - self.cat_file_all = None - self.cat_file_header = None - return self diff --git a/config.py b/config.py deleted file mode 100644 index f1a8832e..00000000 --- a/config.py +++ /dev/null @@ -1,420 +0,0 @@ -# config.py -# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors -# -# This module is part of GitPython and is released under -# the BSD License: http://www.opensource.org/licenses/bsd-license.php -"""Module containing module parser implementation able to properly read and write -configuration files""" - -import re -import os -import ConfigParser as cp -import inspect -import cStringIO - -from git.odict import OrderedDict -from git.util import LockFile - -__all__ = ('GitConfigParser', 'SectionConstraint') - -class MetaParserBuilder(type): - """Utlity class wrapping base-class methods into decorators that assure read-only properties""" - def __new__(metacls, name, bases, clsdict): - """ - Equip all base-class methods with a needs_values decorator, and all non-const methods - with a set_dirty_and_flush_changes decorator in addition to that.""" - kmm = '_mutating_methods_' - if kmm in clsdict: - mutating_methods = clsdict[kmm] - for base in bases: - methods = ( t for t in inspect.getmembers(base, inspect.ismethod) if not t[0].startswith("_") ) - for name, method in methods: - if name in clsdict: - continue - method_with_values = needs_values(method) - if name in mutating_methods: - method_with_values = set_dirty_and_flush_changes(method_with_values) - # END mutating methods handling - - clsdict[name] = method_with_values - # END for each name/method pair - # END for each base - # END if mutating methods configuration is set - - new_type = super(MetaParserBuilder, metacls).__new__(metacls, name, bases, clsdict) - return new_type - - - -def needs_values(func): - """Returns method assuring we read values (on demand) before we try to access them""" - def assure_data_present(self, *args, **kwargs): - self.read() - return func(self, *args, **kwargs) - # END wrapper method - assure_data_present.__name__ = func.__name__ - return assure_data_present - -def set_dirty_and_flush_changes(non_const_func): - """Return method that checks whether given non constant function may be called. - If so, the instance will be set dirty. - Additionally, we flush the changes right to disk""" - def flush_changes(self, *args, **kwargs): - rval = non_const_func(self, *args, **kwargs) - self.write() - return rval - # END wrapper method - flush_changes.__name__ = non_const_func.__name__ - return flush_changes - - -class SectionConstraint(object): - """Constrains a ConfigParser to only option commands which are constrained to - always use the section we have been initialized with. - - It supports all ConfigParser methods that operate on an option""" - __slots__ = ("_config", "_section_name") - _valid_attrs_ = ("get_value", "set_value", "get", "set", "getint", "getfloat", "getboolean", "has_option", - "remove_section", "remove_option", "options") - - def __init__(self, config, section): - self._config = config - self._section_name = section - - def __getattr__(self, attr): - if attr in self._valid_attrs_: - return lambda *args, **kwargs: self._call_config(attr, *args, **kwargs) - return super(SectionConstraint,self).__getattribute__(attr) - - def _call_config(self, method, *args, **kwargs): - """Call the configuration at the given method which must take a section name - as first argument""" - return getattr(self._config, method)(self._section_name, *args, **kwargs) - - @property - def config(self): - """return: Configparser instance we constrain""" - return self._config - - -class GitConfigParser(cp.RawConfigParser, object): - """Implements specifics required to read git style configuration files. - - This variation behaves much like the git.config command such that the configuration - will be read on demand based on the filepath given during initialization. - - The changes will automatically be written once the instance goes out of scope, but - can be triggered manually as well. - - The configuration file will be locked if you intend to change values preventing other - instances to write concurrently. - - :note: - The config is case-sensitive even when queried, hence section and option names - must match perfectly.""" - __metaclass__ = MetaParserBuilder - - - #{ Configuration - # The lock type determines the type of lock to use in new configuration readers. - # They must be compatible to the LockFile interface. - # A suitable alternative would be the BlockingLockFile - t_lock = LockFile - - #} END configuration - - OPTCRE = re.compile( - r'\s?(?P