Retrofit `repo` class as context-man to cleanup global mman on repo-delete by ankostis · Pull Request #555 · gitpython-developers/GitPython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion git/__init__.py
35 changes: 19 additions & 16 deletions git/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,27 +822,30 @@ def _call_process(self, method, *args, **kwargs):
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:
Expand All @@ -851,11 +854,11 @@ def _call_process(self, method, *args, **kwargs):
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]

Expand All @@ -870,7 +873,7 @@ def _call_process(self, method, *args, **kwargs):
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):
"""
Expand Down
14 changes: 14 additions & 0 deletions git/repo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
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__)
Expand Down Expand Up @@ -177,9 +179,21 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
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):
Expand Down
16 changes: 10 additions & 6 deletions git/test/lib/helper.py