summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git/__init__.py3
-rw-r--r--git/cmd.py40
-rw-r--r--git/remote.py4
-rw-r--r--git/repo/base.py14
-rw-r--r--git/test/lib/helper.py16
5 files changed, 50 insertions, 27 deletions
diff --git a/git/__init__.py b/git/__init__.py
index 0514d545..8c31e309 100644
--- a/git/__init__.py
+++ b/git/__init__.py
@@ -49,7 +49,8 @@ from git.util import ( # @NoMove @IgnorePep8
LockFile,
BlockingLockFile,
Stats,
- Actor
+ Actor,
+ rmtree,
)
#} END imports
diff --git a/git/cmd.py b/git/cmd.py
index a4d4c323..702733ea 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -254,14 +254,15 @@ class Git(LazyMixin):
proc.terminate()
proc.wait() # ensure process goes away
except OSError as ex:
- log.info("Ignored error after process has dies: %r", ex)
+ log.info("Ignored error after process had died: %r", ex)
pass # ignore error when process already died
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(proc.pid)), shell=True)
+ if is_win:
+ call(("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(proc.pid)), shell=True)
# END exception handling
def __getattr__(self, attr):
@@ -822,27 +823,30 @@ class Git(LazyMixin):
is realized as non-existent
:param kwargs:
- is a dict of keyword arguments.
- This function accepts the same optional keyword arguments
- as execute().
-
- ``Examples``::
+ It contains key-values for the following:
+ - the :meth:`execute()` kwds, as listed in :var:`execute_kwargs`;
+ - "command options" to be converted by :meth:`transform_kwargs()`;
+ - the `'insert_kwargs_after'` key which its value must match one of ``*args``,
+ and any cmd-options will be appended after the matched arg.
+
+ Examples::
+
git.rev_list('master', max_count=10, header=True)
+
+ turns into::
+
+ git rev-list max-count 10 --header master
: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
+ exec_kwargs = dict((k, v) for k, v in kwargs.items() if k in execute_kwargs)
+ opts_kwargs = dict((k, v) for k, v in kwargs.items() if k not in execute_kwargs)
- insert_after_this_arg = kwargs.pop('insert_kwargs_after', None)
+ insert_after_this_arg = opts_kwargs.pop('insert_kwargs_after', None)
# Prepare the argument list
- opt_args = self.transform_kwargs(**kwargs)
+ opt_args = self.transform_kwargs(**opts_kwargs)
ext_args = self.__unpack_args([a for a in args if a is not None])
if insert_after_this_arg is None:
@@ -851,11 +855,11 @@ class Git(LazyMixin):
try:
index = ext_args.index(insert_after_this_arg)
except ValueError:
- raise ValueError("Couldn't find argument '%s' in args %s to insert kwargs after"
+ raise ValueError("Couldn't find argument '%s' in args %s to insert cmd options after"
% (insert_after_this_arg, str(ext_args)))
# end handle error
args = ext_args[:index + 1] + opt_args + ext_args[index + 1:]
- # end handle kwargs
+ # end handle opts_kwargs
call = [self.GIT_PYTHON_GIT_EXECUTABLE]
@@ -870,7 +874,7 @@ class Git(LazyMixin):
call.append(dashify(method))
call.extend(args)
- return self.execute(call, **_kwargs)
+ return self.execute(call, **exec_kwargs)
def _parse_object_header(self, header_line):
"""
diff --git a/git/remote.py b/git/remote.py
index 336ac5c3..e5480d0e 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -706,8 +706,8 @@ class Remote(LazyMixin, Iterable):
if config.get_value('fetch', default=unset) is unset:
msg = "Remote '%s' has no refspec set.\n"
msg += "You can set it as follows:"
- msg += " 'git config --add \"remote.%s.fetch +refs/heads/*:refs/heads/*\"'." % (self.name, self.name)
- raise AssertionError(msg)
+ msg += " 'git config --add \"remote.%s.fetch +refs/heads/*:refs/heads/*\"'."
+ raise AssertionError(msg % (self.name, self.name))
finally:
config.release()
diff --git a/git/repo/base.py b/git/repo/base.py
index 85f2d036..ace5223f 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -33,6 +33,8 @@ from git.util import Actor, finalize_process, decygpath, hex_to_bin
import os.path as osp
from .fun import rev_parse, is_git_dir, find_submodule_git_dir, touch
+import gc
+import gitdb
log = logging.getLogger(__name__)
@@ -177,9 +179,21 @@ class Repo(object):
args.append(self.git)
self.odb = odbt(*args)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.close()
+
def __del__(self):
+ self.close()
+
+ def close(self):
if self.git:
self.git.clear_cache()
+ gc.collect()
+ gitdb.util.mman.collect()
+ gc.collect()
def __eq__(self, rhs):
if isinstance(rhs, Repo):
diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py
index 743f720c..c3960c24 100644
--- a/git/test/lib/helper.py
+++ b/git/test/lib/helper.py
@@ -7,18 +7,22 @@ from __future__ import print_function
import contextlib
from functools import wraps
-import sys
+import gc
import io
import logging
import os
+import sys
import tempfile
import textwrap
import time
from git.compat import string_types, is_win
from git.util import rmtree, cwd
+import gitdb
import os.path as osp
+
+
if sys.version_info[0:2] == (2, 6):
import unittest2 as unittest
else:
@@ -96,7 +100,6 @@ def with_rw_directory(func):
# a windows-only issue. In fact things should be deleted, as well as
# memory maps closed, once objects go out of scope. For some reason
# though this is not the case here unless we collect explicitly.
- import gc
gc.collect()
if not keep:
rmtree(path)
@@ -144,9 +147,10 @@ def with_rw_repo(working_tree_ref, bare=False):
os.chdir(prev_cwd)
rw_repo.git.clear_cache()
rw_repo = None
- import gc
- gc.collect()
if repo_dir is not None:
+ gc.collect()
+ gitdb.util.mman.collect()
+ gc.collect()
rmtree(repo_dir)
# END rm test repo if possible
# END cleanup
@@ -303,7 +307,8 @@ def with_rw_and_rw_remote_repo(working_tree_ref):
rw_daemon_repo.git.clear_cache()
del rw_repo
del rw_daemon_repo
- import gc
+ gc.collect()
+ gitdb.util.mman.collect()
gc.collect()
if rw_repo_dir:
rmtree(rw_repo_dir)
@@ -357,7 +362,6 @@ class TestBase(TestCase):
each test type has its own repository
"""
from git import Repo
- import gc
gc.collect()
cls.rorepo = Repo(GIT_REPO)