diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2016-09-11 17:40:44 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2016-09-11 17:43:18 +0200 |
commit | 2ba897b12024fd20681b7c2f1b40bdbbccd5df59 (patch) | |
tree | fe1fca314bd72dfceadd36179867e43e9d66e341 | |
parent | ae6e26ed4abac8b5e4e0a893da5546cd165d48e7 (diff) | |
download | gitpython-2ba897b12024fd20681b7c2f1b40bdbbccd5df59.tar.gz |
fix(repo): make it serializable with pickle
It's entirely untested if this repo still does the right thing,
but I'd think it does.
Fixes #504
-rw-r--r-- | doc/source/changes.rst | 1 | ||||
-rw-r--r-- | git/cmd.py | 21 | ||||
-rw-r--r-- | git/repo/base.py | 1 | ||||
-rw-r--r-- | git/test/test_repo.py | 6 |
4 files changed, 26 insertions, 3 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 1feacab8..62f8ab45 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -6,6 +6,7 @@ Changelog ============================= * `tag.commit` will now resolve commits deeply. +* `Repo` objects can now be pickled, which helps with multi-processing. * `DiffIndex.iter_change_type(...)` produces better results when diffing 2.0.8 - Features and Bugfixes @@ -213,6 +213,17 @@ def handle_process_output(process, stdout_handler, stderr_handler, finalizer): def dashify(string): return string.replace('_', '-') + + +def slots_to_dict(self, exclude=()): + return dict((s, getattr(self, s)) for s in self.__slots__ if s not in exclude) + + +def dict_to_slots_and__excluded_are_none(self, d, excluded=()): + for k, v in d.items(): + setattr(self, k, v) + for k in excluded: + setattr(self, k, None) ## -- End Utilities -- @} @@ -235,7 +246,15 @@ class Git(LazyMixin): """ __slots__ = ("_working_dir", "cat_file_all", "cat_file_header", "_version_info", "_git_options", "_environment") - + + _excluded_ = ('cat_file_all', 'cat_file_header', '_version_info') + + def __getstate__(self): + return slots_to_dict(self, exclude=self._excluded_) + + def __setstate__(self, d): + dict_to_slots_and__excluded_are_none(self, d, excluded=self._excluded_) + # CONFIGURATION # The size in bytes read from stdout when copying git's output to another stream max_chunk_size = 1024 * 64 diff --git a/git/repo/base.py b/git/repo/base.py index 312c01ef..0e46ee67 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -93,7 +93,6 @@ class Repo(object): 'git_dir' is the .git repository directory, which is always set.""" DAEMON_EXPORT_FILE = 'git-daemon-export-ok' - __slots__ = ("working_dir", "_working_tree_dir", "git_dir", "_bare", "git", "odb") # precompiled regex re_whitespace = re.compile(r'\s+') diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 17e990f9..e24062c1 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -4,6 +4,8 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +import pickle + from git.test.lib import ( patch, TestBase, @@ -104,13 +106,15 @@ class TestRepo(TestBase): # try from invalid revision that does not exist self.failUnlessRaises(BadName, self.rorepo.tree, 'hello world') + + def test_pickleable(self): + pickle.loads(pickle.dumps(self.rorepo)) def test_commit_from_revision(self): commit = self.rorepo.commit('0.1.4') assert commit.type == 'commit' assert self.rorepo.commit(commit) == commit - def test_commits(self): mc = 10 commits = list(self.rorepo.iter_commits('0.1.6', max_count=mc)) assert len(commits) == mc |