summaryrefslogtreecommitdiff
path: root/lib/git/cmd.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2009-10-11 22:50:44 +0200
committerSebastian Thiel <byronimo@gmail.com>2009-10-11 22:50:44 +0200
commit3c0a65226f038c58fc6d6ed525f38fc00b3579b7 (patch)
treea5b715a490d9cbd8f45eabc1968374c96bdea1c0 /lib/git/cmd.py
parent9c0c2fc4ee2d8a5d0a2de50ba882657989dedc51 (diff)
parentc68459a17ff59043d29c90020fffe651b2164e6a (diff)
downloadgitpython-3c0a65226f038c58fc6d6ed525f38fc00b3579b7.tar.gz
Merge branch 'hierarchyfix' into improvements
* hierarchyfix: Added remaining tests for new base classes and removed some methods whose existance was doubtful or unsafe Fixed remaining tests to deal with the changes commit: fixed failing commit tests as the mocked git command would always return the same thing which does not work anymore - re-implemented it in a more dynamic manner, but in the end tests will have to be revised anyway mode-only change for test system - this should be in a separate repository in fact so that changes are a little more self-contained and not depending on the actual source repository fixed issue in Ref.name implementation which would not handle components properly lazymixin system now supports per-attribute baking, it is up to the class whether it bakes more. This also leads to more efficient use of memory as values are only cached and set when required - the baking system does not require an own tracking variable anymore, and values are only to be cached once - then python will natively find the cache without involving any additional overhead. This works by using __getattr__ instead of __get_attribute__ which would always be called put Tree and Blob onto a new base class suitable to deal with IndexObjects blob tests fixed to deal with changes to the Blob type converted all spaces to tabs ( 4 spaces = 1 tab ) just to allow me and my editor to work with the files properly. Can convert it back for releaes Re-designed the tag testing - it does not use fixtures anymore but dyamically checks the existance of tags within the repository - it basically tests the interface and checks that expected return types are actually returned Intermediate commit: commit,tree and blob objects now derive from object - test is in place which still fails on purpose. Need to integrate tags which can be objects or just a special form of a ref Renamed lazy.py to base.py to have a file for base classes - lazy not yet changed to allow proper rename tracking
Diffstat (limited to 'lib/git/cmd.py')
-rw-r--r--lib/git/cmd.py388
1 files changed, 194 insertions, 194 deletions
diff --git a/lib/git/cmd.py b/lib/git/cmd.py
index 21e235b1..940e35d1 100644
--- a/lib/git/cmd.py
+++ b/lib/git/cmd.py
@@ -13,208 +13,208 @@ from errors import GitCommandError
GIT_PYTHON_TRACE = os.environ.get("GIT_PYTHON_TRACE", False)
execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
- 'with_exceptions', 'with_raw_output')
+ 'with_exceptions', 'with_raw_output')
extra = {}
if sys.platform == 'win32':
- extra = {'shell': True}
+ extra = {'shell': True}
class Git(object):
- """
- The Git class manages communication with the Git binary.
-
+ """
+ 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
+ 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.
- """
- def __init__(self, git_dir=None):
- """
- Initialize this instance with:
-
- ``git_dir``
- Git directory we should work in. If None, we always work in the current
- directory as returned by os.getcwd()
- """
- super(Git, self).__init__()
- self.git_dir = git_dir
-
- def __getattr__(self, name):
- """
- A convenience method as it allows to call the command as if it was
- an object.
- Returns
- 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 get_dir(self):
- """
- Returns
- Git directory we are working on
- """
- return self.git_dir
-
- def execute(self, command,
- istream=None,
- with_keep_cwd=False,
- with_extended_output=False,
- with_exceptions=True,
- with_raw_output=False,
- ):
- """
- Handles executing the command on the shell and consumes and returns
- the returned information (stdout)
-
- ``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.
-
- ``istream``
- Standard input filehandle passed to subprocess.Popen.
-
- ``with_keep_cwd``
- Whether to use the current working directory from os.getcwd().
- GitPython uses get_work_tree() as its working directory by
- default and get_git_dir() for bare repositories.
-
- ``with_extended_output``
- Whether to return a (status, stdout, stderr) tuple.
-
- ``with_exceptions``
- Whether to raise an exception when git returns a non-zero status.
-
- ``with_raw_output``
- Whether to avoid stripping off trailing whitespace.
-
- Returns::
-
- str(output) # extended_output = False (Default)
- tuple(int(status), str(stdout), str(stderr)) # 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.git_dir is None:
- cwd = os.getcwd()
- else:
- cwd=self.git_dir
-
- # Start the process
- proc = subprocess.Popen(command,
- cwd=cwd,
- stdin=istream,
- stderr=subprocess.PIPE,
- stdout=subprocess.PIPE,
- **extra
- )
-
- # Wait for the process to return
- try:
- stdout_value = proc.stdout.read()
- stderr_value = proc.stderr.read()
- status = proc.wait()
- finally:
- proc.stdout.close()
- proc.stderr.close()
-
- # Strip off trailing whitespace by default
- if not with_raw_output:
- stdout_value = stdout_value.rstrip()
- stderr_value = stderr_value.rstrip()
-
- if with_exceptions and status != 0:
- raise GitCommandError(command, status, stderr_value)
-
- if GIT_PYTHON_TRACE == 'full':
- if stderr_value:
- print "%s -> %d: '%s' !! '%s'" % (command, status, stdout_value, stderr_value)
- elif stdout_value:
- print "%s -> %d: '%s'" % (command, status, stdout_value)
- else:
- print "%s -> %d" % (command, status)
-
- # 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 = []
- 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
-
- def _call_process(self, method, *args, **kwargs):
- """
- Run the given git command with the specified arguments and return
- the result as a String
-
- ``method``
- is the command. Contained "_" characters will be converted to dashes,
- such as in 'ls_files' to call 'ls-files'.
-
- ``args``
- is the list of arguments
-
- ``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)
-
- Returns
- Same as execute()
- """
-
- # Handle optional arguments prior to calling transform_kwargs
- # otherwise these'll end up in args, which is bad.
- _kwargs = {}
- 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 = map(str, args)
- args = opt_args + ext_args
-
- call = ["git", dashify(method)]
- call.extend(args)
-
- return self.execute(call, **_kwargs)
+ 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.
+ """
+ def __init__(self, git_dir=None):
+ """
+ Initialize this instance with:
+
+ ``git_dir``
+ Git directory we should work in. If None, we always work in the current
+ directory as returned by os.getcwd()
+ """
+ super(Git, self).__init__()
+ self.git_dir = git_dir
+
+ def __getattr__(self, name):
+ """
+ A convenience method as it allows to call the command as if it was
+ an object.
+ Returns
+ 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 get_dir(self):
+ """
+ Returns
+ Git directory we are working on
+ """
+ return self.git_dir
+
+ def execute(self, command,
+ istream=None,
+ with_keep_cwd=False,
+ with_extended_output=False,
+ with_exceptions=True,
+ with_raw_output=False,
+ ):
+ """
+ Handles executing the command on the shell and consumes and returns
+ the returned information (stdout)
+
+ ``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.
+
+ ``istream``
+ Standard input filehandle passed to subprocess.Popen.
+
+ ``with_keep_cwd``
+ Whether to use the current working directory from os.getcwd().
+ GitPython uses get_work_tree() as its working directory by
+ default and get_git_dir() for bare repositories.
+
+ ``with_extended_output``
+ Whether to return a (status, stdout, stderr) tuple.
+
+ ``with_exceptions``
+ Whether to raise an exception when git returns a non-zero status.
+
+ ``with_raw_output``
+ Whether to avoid stripping off trailing whitespace.
+
+ Returns::
+
+ str(output) # extended_output = False (Default)
+ tuple(int(status), str(stdout), str(stderr)) # 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.git_dir is None:
+ cwd = os.getcwd()
+ else:
+ cwd=self.git_dir
+
+ # Start the process
+ proc = subprocess.Popen(command,
+ cwd=cwd,
+ stdin=istream,
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ **extra
+ )
+
+ # Wait for the process to return
+ try:
+ stdout_value = proc.stdout.read()
+ stderr_value = proc.stderr.read()
+ status = proc.wait()
+ finally:
+ proc.stdout.close()
+ proc.stderr.close()
+
+ # Strip off trailing whitespace by default
+ if not with_raw_output:
+ stdout_value = stdout_value.rstrip()
+ stderr_value = stderr_value.rstrip()
+
+ if with_exceptions and status != 0:
+ raise GitCommandError(command, status, stderr_value)
+
+ if GIT_PYTHON_TRACE == 'full':
+ if stderr_value:
+ print "%s -> %d: '%s' !! '%s'" % (command, status, stdout_value, stderr_value)
+ elif stdout_value:
+ print "%s -> %d: '%s'" % (command, status, stdout_value)
+ else:
+ print "%s -> %d" % (command, status)
+
+ # 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 = []
+ 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
+
+ def _call_process(self, method, *args, **kwargs):
+ """
+ Run the given git command with the specified arguments and return
+ the result as a String
+
+ ``method``
+ is the command. Contained "_" characters will be converted to dashes,
+ such as in 'ls_files' to call 'ls-files'.
+
+ ``args``
+ is the list of arguments
+
+ ``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)
+
+ Returns
+ Same as execute()
+ """
+
+ # Handle optional arguments prior to calling transform_kwargs
+ # otherwise these'll end up in args, which is bad.
+ _kwargs = {}
+ 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 = map(str, args)
+ args = opt_args + ext_args
+
+ call = ["git", dashify(method)]
+ call.extend(args)
+
+ return self.execute(call, **_kwargs)