summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Musso <hashar@free.fr>2014-11-16 20:51:04 +0100
committerAntoine Musso <hashar@free.fr>2014-11-16 20:51:21 +0100
commitbe34ec23c48d6d5d8fd2ef4491981f6fb4bab8e6 (patch)
tree7d0124054760421d95a6f675d8e843e42a72ad82
parentf5d11b750ecc982541d1f936488248f0b42d75d3 (diff)
downloadgitpython-be34ec23c48d6d5d8fd2ef4491981f6fb4bab8e6.tar.gz
pep8 linting (blank lines expectations)
E301 expected 1 blank line, found 0 E302 expected 2 blank lines, found 1 E303 too many blank lines (n)
-rw-r--r--git/cmd.py7
-rw-r--r--git/config.py12
-rw-r--r--git/db.py5
-rw-r--r--git/diff.py6
-rw-r--r--git/exc.py10
-rw-r--r--git/index/base.py9
-rw-r--r--git/index/fun.py6
-rw-r--r--git/index/typ.py4
-rw-r--r--git/index/util.py6
-rw-r--r--git/objects/base.py3
-rw-r--r--git/objects/blob.py2
-rw-r--r--git/objects/commit.py6
-rw-r--r--git/objects/fun.py6
-rw-r--r--git/objects/submodule/base.py5
-rw-r--r--git/objects/submodule/root.py5
-rw-r--r--git/objects/submodule/util.py7
-rw-r--r--git/objects/tag.py2
-rw-r--r--git/objects/tree.py6
-rw-r--r--git/objects/util.py10
-rw-r--r--git/odict.py68
-rw-r--r--git/refs/head.py4
-rw-r--r--git/refs/log.py2
-rw-r--r--git/refs/reference.py6
-rw-r--r--git/refs/remote.py2
-rw-r--r--git/refs/symbolic.py5
-rw-r--r--git/refs/tag.py3
-rw-r--r--git/remote.py8
-rw-r--r--git/repo/base.py3
-rw-r--r--git/repo/fun.py7
-rw-r--r--git/test/lib/asserts.py8
-rw-r--r--git/test/lib/helper.py13
-rw-r--r--git/test/performance/lib.py2
-rw-r--r--git/test/performance/test_commit.py1
-rw-r--r--git/test/performance/test_streams.py4
-rw-r--r--git/test/performance/test_utils.py4
-rw-r--r--git/test/test_actor.py2
-rw-r--r--git/test/test_base.py1
-rw-r--r--git/test/test_blob.py1
-rw-r--r--git/test/test_commit.py1
-rw-r--r--git/test/test_config.py1
-rw-r--r--git/test/test_db.py1
-rw-r--r--git/test/test_diff.py1
-rw-r--r--git/test/test_fun.py4
-rw-r--r--git/test/test_git.py3
-rw-r--r--git/test/test_index.py8
-rw-r--r--git/test/test_reflog.py2
-rw-r--r--git/test/test_refs.py8
-rw-r--r--git/test/test_remote.py5
-rw-r--r--git/test/test_repo.py9
-rw-r--r--git/test/test_stats.py1
-rw-r--r--git/test/test_submodule.py9
-rw-r--r--git/test/test_tree.py2
-rw-r--r--git/test/test_util.py3
-rw-r--r--git/util.py22
54 files changed, 245 insertions, 96 deletions
diff --git a/git/cmd.py b/git/cmd.py
index c655cdc8..272ff32a 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -23,11 +23,13 @@ execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
__all__ = ('Git', )
+
def dashify(string):
return string.replace('_', '-')
class Git(LazyMixin):
+
"""
The Git class manages communication with the Git binary.
@@ -59,8 +61,8 @@ class Git(LazyMixin):
_git_exec_env_var = "GIT_PYTHON_GIT_EXECUTABLE"
GIT_PYTHON_GIT_EXECUTABLE = os.environ.get(_git_exec_env_var, git_exec_name)
-
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.
@@ -114,6 +116,7 @@ class Git(LazyMixin):
# 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
@@ -213,7 +216,6 @@ class Git(LazyMixin):
self._stream.read(bytes_left + 1)
# END handle incomplete read
-
def __init__(self, working_dir=None):
"""Initialize this instance with:
@@ -247,7 +249,6 @@ class Git(LazyMixin):
super(Git, self)._set_cache_(attr)
#END handle version info
-
@property
def working_dir(self):
""":return: Git directory we are working on"""
diff --git a/git/config.py b/git/config.py
index 5ad69c6a..913b965a 100644
--- a/git/config.py
+++ b/git/config.py
@@ -17,7 +17,9 @@ 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):
"""
@@ -45,9 +47,9 @@ class MetaParserBuilder(type):
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)
@@ -55,10 +57,12 @@ def needs_values(func):
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()
@@ -69,6 +73,7 @@ def set_dirty_and_flush_changes(non_const_func):
class SectionConstraint(object):
+
"""Constrains a ConfigParser to only option commands which are constrained to
always use the section we have been initialized with.
@@ -98,6 +103,7 @@ class SectionConstraint(object):
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
@@ -114,7 +120,6 @@ class GitConfigParser(cp.RawConfigParser, object):
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.
@@ -172,7 +177,6 @@ class GitConfigParser(cp.RawConfigParser, object):
self._lock._obtain_lock()
# END read-only check
-
def __del__(self):
"""Write pending changes if required and release locks"""
# checking for the lock here makes sure we do not raise during write()
@@ -261,7 +265,6 @@ class GitConfigParser(cp.RawConfigParser, object):
if e:
raise e
-
def read(self):
"""Reads the data stored in the files we have been initialized with. It will
ignore files that cannot be read, possibly leaving an empty configuration
@@ -311,7 +314,6 @@ class GitConfigParser(cp.RawConfigParser, object):
write_section(cp.DEFAULTSECT, self._defaults)
map(lambda t: write_section(t[0],t[1]), self._sections.items())
-
@needs_values
def write(self):
"""Write changes to our file, if there are changes at all
diff --git a/git/db.py b/git/db.py
index 0d12aeb4..415f7aa4 100644
--- a/git/db.py
+++ b/git/db.py
@@ -20,7 +20,10 @@ from gitdb.db import LooseObjectDB
__all__ = ('GitCmdObjectDB', 'GitDB' )
#class GitCmdObjectDB(CompoundDB, ObjectDBW):
+
+
class GitCmdObjectDB(LooseObjectDB):
+
"""A database representing the default git object store, which includes loose
objects, pack files and an alternates file
@@ -28,6 +31,7 @@ class GitCmdObjectDB(LooseObjectDB):
:note: for now, we use the git command to do all the lookup, just until he
have packs and the other implementations
"""
+
def __init__(self, root_path, git):
"""Initialize this instance with the root and a git command"""
super(GitCmdObjectDB, self).__init__(root_path)
@@ -42,7 +46,6 @@ class GitCmdObjectDB(LooseObjectDB):
hexsha, typename, size, stream = self._git.stream_object_data(bin_to_hex(sha))
return OStream(hex_to_bin(hexsha), typename, size, stream)
-
# { Interface
def partial_to_complete_sha_hex(self, partial_hexsha):
diff --git a/git/diff.py b/git/diff.py
index b4d2bae8..a8b12fef 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -14,7 +14,9 @@ from gitdb.util import hex_to_bin
__all__ = ('Diffable', 'DiffIndex', 'Diff')
+
class Diffable(object):
+
"""Common interface for all object that can be diffed against another object of compatible type.
:note:
@@ -109,6 +111,7 @@ class Diffable(object):
class DiffIndex(list):
+
"""Implements an Index for diffs, allowing a list of Diffs to be queried by
the diff properties.
@@ -120,7 +123,6 @@ class DiffIndex(list):
# M = modified
change_type = ("A", "D", "R", "M")
-
def iter_change_type(self, change_type):
"""
:return:
@@ -149,6 +151,7 @@ class DiffIndex(list):
class Diff(object):
+
"""A Diff contains diff information between two Trees.
It contains two sides a and b of the diff, members are prefixed with
@@ -228,7 +231,6 @@ class Diff(object):
self.diff = diff
-
def __eq__(self, other):
for name in self.__slots__:
if getattr(self, name) != getattr(other, name):
diff --git a/git/exc.py b/git/exc.py
index fac7cde5..db78853e 100644
--- a/git/exc.py
+++ b/git/exc.py
@@ -7,16 +7,21 @@
from gitdb.exc import *
+
class InvalidGitRepositoryError(Exception):
+
""" Thrown if the given repository appears to have an invalid format. """
class NoSuchPathError(OSError):
+
""" Thrown if a path could not be access by the system. """
class GitCommandError(Exception):
+
""" Thrown if execution of the git command fails with non-zero status code. """
+
def __init__(self, command, status, stderr=None, stdout=None):
self.stderr = stderr
self.stdout = stdout
@@ -32,6 +37,7 @@ class GitCommandError(Exception):
class CheckoutError( Exception ):
+
"""Thrown if a file could not be checked out from the index as it contained
changes.
@@ -44,6 +50,7 @@ class CheckoutError( Exception ):
The .valid_files attribute contains a list of relative paths to files that
were checked out successfully and hence match the version stored in the
index"""
+
def __init__(self, message, failed_files, valid_files, failed_reasons):
Exception.__init__(self, message)
self.failed_files = failed_files
@@ -55,8 +62,11 @@ class CheckoutError( Exception ):
class CacheError(Exception):
+
"""Base for all errors related to the git index, which is called cache internally"""
+
class UnmergedEntriesError(CacheError):
+
"""Thrown if an operation cannot proceed as there are still unmerged
entries in the cache"""
diff --git a/git/index/base.py b/git/index/base.py
index 9a3e80ea..601f1c0e 100644
--- a/git/index/base.py
+++ b/git/index/base.py
@@ -71,6 +71,7 @@ __all__ = ( 'IndexFile', 'CheckoutError' )
class IndexFile(LazyMixin, diff.Diffable, Serializable):
+
"""
Implements an Index that can be manipulated using a native implementation in
order to save git command function calls wherever possible.
@@ -174,7 +175,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
(ignore_tree_extension_data and None) or self._extension_data)
return self
-
#} END serializable interface
def write(self, file_path = None, ignore_tree_extension_data=False):
@@ -273,7 +273,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
inst.entries = entries
return inst
-
@classmethod
def from_tree(cls, repo, *treeish, **kwargs):
"""Merge the given treeish revisions into a new index which is returned.
@@ -519,7 +518,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# copy changed trees only
mdb.stream_copy(mdb.sha_iter(), self.repo.odb)
-
# note: additional deserialization could be saved if write_tree_from_cache
# would return sorted tree entries
root_tree = Tree(self.repo, binsha, path='')
@@ -664,7 +662,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
del(paths[:])
# END rewrite paths
-
def store_path(filepath):
"""Store file at filepath in the database and return the base index entry"""
st = os.lstat(filepath) # handles non-symlinks as well
@@ -681,7 +678,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
istream.binsha, 0, to_native_path_linux(filepath)))
# END utility method
-
# HANDLE PATHS
if paths:
assert len(entries_added) == 0
@@ -691,7 +687,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
# END for each filepath
# END path handling
-
# HANDLE ENTRIES
if entries:
null_mode_entries = [ e for e in entries if e.mode == 0 ]
@@ -866,7 +861,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
return out
# END handle dryrun
-
# now apply the actual operation
kwargs.pop('dry_run')
self.repo.git.mv(args, paths, **kwargs)
@@ -989,7 +983,6 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
raise CheckoutError("Some files could not be checked out from the index due to local modifications", failed_files, valid_files, failed_reasons)
# END stderr handler
-
if paths is None:
args.append("--all")
kwargs['as_process'] = 1
diff --git a/git/index/fun.py b/git/index/fun.py
index ede7e43f..2fb09675 100644
--- a/git/index/fun.py
+++ b/git/index/fun.py
@@ -99,6 +99,7 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1
# write the sha over the content
stream.write_sha()
+
def read_header(stream):
"""Return tuple(version_long, num_entries) from the given stream"""
type_id = stream.read(4)
@@ -110,6 +111,7 @@ def read_header(stream):
assert version in (1, 2)
return version, num_entries
+
def entry_key(*entry):
""":return: Key suitable to be used for the index.entries dictionary
:param entry: One instance of type BaseIndexEntry or the path and the stage"""
@@ -119,6 +121,7 @@ def entry_key(*entry):
return tuple(entry)
# END handle entry
+
def read_cache(stream):
"""Read a cache file from the given stream
:return: tuple(version, entries_dict, extension_data, content_sha)
@@ -166,6 +169,7 @@ def read_cache(stream):
return (version, entries, extension_data, content_sha)
+
def write_tree_from_cache(entries, odb, sl, si=0):
"""Create a tree from the given sorted list of entries and put the respective
trees into the given object database
@@ -221,9 +225,11 @@ def write_tree_from_cache(entries, odb, sl, si=0):
istream = odb.store(IStream(str_tree_type, len(sio.getvalue()), sio))
return (istream.binsha, tree_items)
+
def _tree_entry_to_baseindexentry(tree_entry, stage):
return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))
+
def aggressive_tree_merge(odb, tree_shas):
"""
:return: list of BaseIndexEntries representing the aggressive merge of the given
diff --git a/git/index/typ.py b/git/index/typ.py
index 97dff59e..2dd82b62 100644
--- a/git/index/typ.py
+++ b/git/index/typ.py
@@ -21,7 +21,9 @@ CE_STAGESHIFT = 12
#} END invariants
+
class BlobFilter(object):
+
"""
Predicate to be used by iter_blobs allowing to filter only return blobs which
match the given list of directories or files.
@@ -47,6 +49,7 @@ class BlobFilter(object):
class BaseIndexEntry(tuple):
+
"""Small Brother of an index entry which can be created to describe changes
done to the index in which case plenty of additional information is not requried.
@@ -109,6 +112,7 @@ class BaseIndexEntry(tuple):
class IndexEntry(BaseIndexEntry):
+
"""Allows convenient access to IndexEntry data without completely unpacking it.
Attributes usully accessed often are cached in the tuple whereas others are
diff --git a/git/index/util.py b/git/index/util.py
index 7211b4fc..289a3cb1 100644
--- a/git/index/util.py
+++ b/git/index/util.py
@@ -13,6 +13,7 @@ unpack = struct.unpack
#} END aliases
class TemporaryFileSwap(object):
+
"""Utility class moving a file to a temporary location within the same directory
and moving it back on to where on object deletion."""
__slots__ = ("file_path", "tmp_file_path")
@@ -45,6 +46,7 @@ def post_clear_cache(func):
This decorator will not be required once all functions are implemented
natively which in fact is possible, but probably not feasible performance wise.
"""
+
def post_clear_cache_if_not_raised(self, *args, **kwargs):
rval = func(self, *args, **kwargs)
self._delete_entries_cache()
@@ -54,10 +56,12 @@ def post_clear_cache(func):
post_clear_cache_if_not_raised.__name__ = func.__name__
return post_clear_cache_if_not_raised
+
def default_index(func):
"""Decorator assuring the wrapped method may only run if we are the default
repository index. This is as we rely on git commands that operate
on that index only. """
+
def check_default_index(self, *args, **kwargs):
if self._file_path != self._index_path():
raise AssertionError( "Cannot call %r on indices that do not represent the default git index" % func.__name__ )
@@ -67,9 +71,11 @@ def default_index(func):
check_default_index.__name__ = func.__name__
return check_default_index
+
def git_working_dir(func):
"""Decorator which changes the current working dir to the one of the git
repository in order to assure relative paths are handled correctly"""
+
def set_git_working_dir(self, *args, **kwargs):
cur_wd = os.getcwd()
os.chdir(self.repo.working_tree_dir)
diff --git a/git/objects/base.py b/git/objects/base.py
index 9e73e2f3..fce41a3d 100644
--- a/git/objects/base.py
+++ b/git/objects/base.py
@@ -17,7 +17,9 @@ _assertion_msg_format = "Created object %r whose python type %r disagrees with t
__all__ = ("Object", "IndexObject")
+
class Object(LazyMixin):
+
"""Implements an Object which may be Blobs, Trees, Commits and Tags"""
NULL_HEX_SHA = '0'*40
NULL_BIN_SHA = '\0'*20
@@ -120,6 +122,7 @@ class Object(LazyMixin):
class IndexObject(Object):
+
"""Base for all objects that can be part of the index file , namely Tree, Blob and
SubModule objects"""
__slots__ = ("path", "mode")
diff --git a/git/objects/blob.py b/git/objects/blob.py
index fd748537..5f00a1ff 100644
--- a/git/objects/blob.py
+++ b/git/objects/blob.py
@@ -9,7 +9,9 @@ import base
__all__ = ('Blob', )
+
class Blob(base.IndexObject):
+
"""A Blob encapsulates a git blob object"""
DEFAULT_MIME_TYPE = "text/plain"
type = "blob"
diff --git a/git/objects/commit.py b/git/objects/commit.py
index db1493d5..b2ed02c0 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -35,7 +35,9 @@ import sys
__all__ = ('Commit', )
+
class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
+
"""Wraps a git Commit object.
This class will act lazily on some of its attributes and will query the
@@ -52,7 +54,6 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
# INVARIANTS
default_encoding = "UTF-8"
-
# object configuration
type = "commit"
__slots__ = ("tree",
@@ -158,7 +159,6 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
else:
return len(self.repo.git.rev_list(self.hexsha, **kwargs).splitlines())
-
@property
def name_rev(self):
"""
@@ -257,7 +257,6 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
if hasattr(proc_or_stream, 'wait'):
finalize_process(proc_or_stream)
-
@classmethod
def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False):
"""Commit the given tree, creating a commit object.
@@ -329,7 +328,6 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
enc_section, enc_option = cls.conf_encoding.split('.')
conf_encoding = cr.get_value(enc_section, enc_option, cls.default_encoding)
-
# if the tree is no object, make sure we create one - otherwise
# the created commit object is invalid
if isinstance(tree, str):
diff --git a/git/objects/fun.py b/git/objects/fun.py
index a046d6d5..8f5a5cc2 100644
--- a/git/objects/fun.py
+++ b/git/objects/fun.py
@@ -5,8 +5,6 @@ __all__ = ('tree_to_stream', 'tree_entries_from_data', 'traverse_trees_recursive
'traverse_tree_recursive')
-
-
def tree_to_stream(entries, write):
"""Write the give list of entries into a stream using its write method
:param entries: **sorted** list of tuples with (binsha, mode, name)
@@ -88,7 +86,6 @@ def tree_entries_from_data(data):
return out
-
def _find_by_name(tree_data, name, is_dir, start_at):
"""return data entry matching the given name and tree mode
or None.
@@ -110,12 +107,14 @@ def _find_by_name(tree_data, name, is_dir, start_at):
# END for each item
return None
+
def _to_full_path(item, path_prefix):
"""Rebuild entry with given path prefix"""
if not item:
return item
return (item[0], item[1], path_prefix+item[2])
+
def traverse_trees_recursive(odb, tree_shas, path_prefix):
"""
:return: list with entries according to the given binary tree-shas.
@@ -182,6 +181,7 @@ def traverse_trees_recursive(odb, tree_shas, path_prefix):
# END for each tree_data chunk
return out
+
def traverse_tree_recursive(odb, tree_sha, path_prefix):
"""
:return: list of entries of the tree pointed to by the binary tree_sha. An entry
diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
index 730642ed..42048028 100644
--- a/git/objects/submodule/base.py
+++ b/git/objects/submodule/base.py
@@ -34,6 +34,7 @@ __all__ = ["Submodule", "UpdateProgress"]
class UpdateProgress(RemoteProgress):
+
"""Class providing detailed progress information to the caller who should
derive from it and implement the ``update(...)`` message"""
CLONE, FETCH, UPDWKTREE = [1 << x for x in range(RemoteProgress._num_op_codes, RemoteProgress._num_op_codes+3)]
@@ -53,6 +54,7 @@ UPDWKTREE = UpdateProgress.UPDWKTREE
# mechanism which cause plenty of trouble of the only reason for packages and
# modules is refactoring - subpackages shoudn't depend on parent packages
class Submodule(util.IndexObject, Iterable, Traversable):
+
"""Implements access to a git submodule. They are special in that their sha
represents a commit in the submodule's repository which is to be checked out
at the path of this instance.
@@ -387,7 +389,6 @@ class Submodule(util.IndexObject, Iterable, Traversable):
#END handle dry-run
progress.update(END|CLONE, 0, 1, prefix+"Done cloning to %s" % module_path)
-
if not dry_run:
# see whether we have a valid branch to checkout
try:
@@ -415,7 +416,6 @@ class Submodule(util.IndexObject, Iterable, Traversable):
#END handle dry_run
#END handle initalization
-
# DETERMINE SHAS TO CHECKOUT
############################
binsha = self.binsha
@@ -549,7 +549,6 @@ class Submodule(util.IndexObject, Iterable, Traversable):
renamed_module = True
#END move physical module
-
# rename the index entry - have to manipulate the index directly as
# git-mv cannot be used on submodules ... yeah
try:
diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py
index fb0a65c3..62ad1f05 100644
--- a/git/objects/submodule/root.py
+++ b/git/objects/submodule/root.py
@@ -11,6 +11,7 @@ __all__ = ["RootModule", "RootUpdateProgress"]
class RootUpdateProgress(UpdateProgress):
+
"""Utility class which adds more opcodes to the UpdateProgress"""
REMOVE, PATHCHANGE, BRANCHCHANGE, URLCHANGE = [1 << x for x in range(UpdateProgress._num_op_codes, UpdateProgress._num_op_codes+4)]
_num_op_codes = UpdateProgress._num_op_codes+4
@@ -24,7 +25,9 @@ BRANCHCHANGE = RootUpdateProgress.BRANCHCHANGE
URLCHANGE = RootUpdateProgress.URLCHANGE
PATHCHANGE = RootUpdateProgress.PATHCHANGE
+
class RootModule(Submodule):
+
"""A (virtual) Root of all submodules in the given repository. It can be used
to more easily traverse all submodules of the master repository"""
@@ -45,7 +48,6 @@ class RootModule(Submodule):
branch_path = git.Head.to_full_path(self.k_head_default)
)
-
def _clear_cache(self):
"""May not do anything"""
pass
@@ -107,7 +109,6 @@ class RootModule(Submodule):
previous_commit = repo.commit(previous_commit) # obtain commit object
# END handle previous commit
-
psms = self.list_items(repo, parent_commit=previous_commit)
sms = self.list_items(repo)
spsms = set(psms)
diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py
index 237321e2..47b45109 100644
--- a/git/objects/submodule/util.py
+++ b/git/objects/submodule/util.py
@@ -9,22 +9,27 @@ __all__ = ( 'sm_section', 'sm_name', 'mkhead', 'unbare_repo', 'find_first_remote
#{ Utilities
+
def sm_section(name):
""":return: section title used in .gitmodules configuration file"""
return 'submodule "%s"' % name
+
def sm_name(section):
""":return: name of the submodule as parsed from the section name"""
section = section.strip()
return section[11:-1]
+
def mkhead(repo, path):
""":return: New branch/head instance"""
return git.Head(repo, git.Head.to_full_path(path))
+
def unbare_repo(func):
"""Methods with this decorator raise InvalidGitRepositoryError if they
encounter a bare repository"""
+
def wrapper(self, *args, **kwargs):
if self.repo.bare:
raise InvalidGitRepositoryError("Method '%s' cannot operate on bare repositories" % func.__name__)
@@ -34,6 +39,7 @@ def unbare_repo(func):
wrapper.__name__ = func.__name__
return wrapper
+
def find_first_remote_branch(remotes, branch_name):
"""Find the remote branch matching the name of the given branch or raise InvalidGitRepositoryError"""
for remote in remotes:
@@ -51,6 +57,7 @@ def find_first_remote_branch(remotes, branch_name):
#{ Classes
class SubmoduleConfigParser(GitConfigParser):
+
"""
Catches calls to _write, and updates the .gitmodules blob in the index
with the new data, if we have written into a stream. Otherwise it will
diff --git a/git/objects/tag.py b/git/objects/tag.py
index b34c5945..3690dc45 100644
--- a/git/objects/tag.py
+++ b/git/objects/tag.py
@@ -13,7 +13,9 @@ from util import (
__all__ = ("TagObject", )
+
class TagObject(base.Object):
+
"""Non-Lightweight tag carrying additional information about an object we are pointing to."""
type = "tag"
__slots__ = ( "object", "tag", "tagger", "tagged_date", "tagger_tz_offset", "message" )
diff --git a/git/objects/tree.py b/git/objects/tree.py
index 92b0feca..4984823e 100644
--- a/git/objects/tree.py
+++ b/git/objects/tree.py
@@ -21,7 +21,9 @@ from gitdb.util import (
__all__ = ("TreeModifier", "Tree")
+
class TreeModifier(object):
+
"""A utility class providing methods to alter the underlying cache in a list-like fashion.
Once all adjustments are complete, the _cache, which really is a refernce to
@@ -101,6 +103,7 @@ class TreeModifier(object):
class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable):
+
"""Tree objects represent an ordered list of Blobs and other Trees.
``Tree as a list``::
@@ -128,7 +131,6 @@ class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable):
# tree id added once Tree is defined
}
-
def __init__(self, repo, binsha, mode=tree_id<<12, path=None):
super(Tree, self).__init__(repo, binsha, mode, path)
@@ -190,7 +192,6 @@ class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable):
raise KeyError( msg % file )
# END handle long paths
-
@property
def trees(self):
""":return: list(Tree, ...) list of trees directly below this tree"""
@@ -239,7 +240,6 @@ class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable):
raise TypeError( "Invalid index type: %r" % item )
-
def __contains__(self, item):
if isinstance(item, IndexObject):
for info in self._cache:
diff --git a/git/objects/util.py b/git/objects/util.py
index f9dffd81..9f947fcc 100644
--- a/git/objects/util.py
+++ b/git/objects/util.py
@@ -22,6 +22,7 @@ __all__ = ('get_object_type_by_name', 'parse_date', 'parse_actor_and_date',
#{ Functions
+
def mode_str_to_int(modestr):
"""
:param modestr: string like 755 or 644 or 100644 - only the last 6 chars will be used
@@ -36,6 +37,7 @@ def mode_str_to_int(modestr):
# END for each char
return mode
+
def get_object_type_by_name(object_type_name):
"""
:return: type suitable to handle the given object type name.
@@ -59,6 +61,7 @@ def get_object_type_by_name(object_type_name):
else:
raise ValueError("Cannot handle unknown object type: %s" % object_type_name)
+
def utctz_to_altz(utctz):
"""we convert utctz to the timezone in seconds, it is the format time.altzone
returns. Git stores it as UTC timezone which has the opposite sign as well,
@@ -66,6 +69,7 @@ def utctz_to_altz(utctz):
:param utctz: git utc timezone string, i.e. +0200"""
return -1 * int(float(utctz)/100*3600)
+
def altz_to_utctz_str(altz):
"""As above, but inverses the operation, returning a string that can be used
in commit objects"""
@@ -92,6 +96,7 @@ def verify_utctz(offset):
# END for each char
return offset
+
def parse_date(string_date):
"""
Parse the given date as one of the following
@@ -169,6 +174,7 @@ def parse_date(string_date):
_re_actor_epoch = re.compile(r'^.+? (.*) (\d+) ([+-]\d+).*$')
_re_only_actor = re.compile(r'^.+? (.*)$')
+
def parse_actor_and_date(line):
"""Parse out the actor (author or committer) info from a line like::
@@ -190,12 +196,14 @@ def parse_actor_and_date(line):
#{ Classes
class ProcessStreamAdapter(object):
+
"""Class wireing all calls to the contained Process instance.
Use this type to hide the underlying process to provide access only to a specified
stream. The process is usually wrapped into an AutoInterrupt class to kill
it if the instance goes out of scope."""
__slots__ = ("_proc", "_stream")
+
def __init__(self, process, stream_name):
self._proc = process
self._stream = getattr(process, stream_name)
@@ -205,6 +213,7 @@ class ProcessStreamAdapter(object):
class Traversable(object):
+
"""Simple interface to perforam depth-first or breadth-first traversals
into one direction.
Subclasses only need to implement one function.
@@ -303,6 +312,7 @@ class Traversable(object):
class Serializable(object):
+
"""Defines methods to serialize and deserialize objects from and into a data stream"""
__slots__ = tuple()
diff --git a/git/odict.py b/git/odict.py
index d4f84ac3..238c0ea8 100644
--- a/git/odict.py
+++ b/git/odict.py
@@ -35,7 +35,9 @@ if INTP_VER < (2, 2):
import types, warnings
+
class OrderedDict(dict):
+
"""
A class of dictionary that keeps the insertion order of keys.
@@ -537,6 +539,7 @@ class OrderedDict(dict):
Traceback (most recent call last):
StopIteration
"""
+
def make_iter(self=self):
keys = self.iterkeys()
while True:
@@ -574,6 +577,7 @@ class OrderedDict(dict):
Traceback (most recent call last):
StopIteration
"""
+
def make_iter(self=self):
keys = self.iterkeys()
while True:
@@ -871,8 +875,10 @@ class OrderedDict(dict):
"""
self._sequence.sort(*args, **kwargs)
+
class Keys(object):
# FIXME: should this object be a subclass of list?
+
"""
Custom object for accessing the keys of an OrderedDict.
@@ -933,37 +939,61 @@ class Keys(object):
# FIXME: do we need to check if we are comparing with another ``Keys``
# object? (like the __cast method of UserList)
def __lt__(self, other): return self._main._sequence < other
+
def __le__(self, other): return self._main._sequence <= other
+
def __eq__(self, other): return self._main._sequence == other
+
def __ne__(self, other): return self._main._sequence != other
+
def __gt__(self, other): return self._main._sequence > other
+
def __ge__(self, other): return self._main._sequence >= other
# FIXME: do we need __cmp__ as well as rich comparisons?
+
def __cmp__(self, other): return cmp(self._main._sequence, other)
def __contains__(self, item): return item in self._main._sequence
+
def __len__(self): return len(self._main._sequence)
+
def __iter__(self): return self._main.iterkeys()
+
def count(self, item): return self._main._sequence.count(item)
+
def index(self, item, *args): return self._main._sequence.index(item, *args)
+
def reverse(self): self._main._sequence.reverse()
+
def sort(self, *args, **kwds): self._main._sequence.sort(*args, **kwds)
+
def __mul__(self, n): return self._main._sequence*n
__rmul__ = __mul__
+
def __add__(self, other): return self._main._sequence + other
+
def __radd__(self, other): return other + self._main._sequence
## following methods not implemented for keys ##
def __delitem__(self, i): raise TypeError('Can\'t delete items from keys')
+
def __iadd__(self, other): raise TypeError('Can\'t add in place to keys')
+
def __imul__(self, n): raise TypeError('Can\'t multiply keys in place')
+
def append(self, item): raise TypeError('Can\'t append items to keys')
+
def insert(self, i, item): raise TypeError('Can\'t insert items into keys')
+
def pop(self, i=-1): raise TypeError('Can\'t pop items from keys')
+
def remove(self, item): raise TypeError('Can\'t remove items from keys')
+
def extend(self, other): raise TypeError('Can\'t extend keys')
+
class Items(object):
+
"""
Custom object for accessing the items of an OrderedDict.
@@ -1018,23 +1048,38 @@ class Items(object):
# FIXME: do we need to check if we are comparing with another ``Items``
# object? (like the __cast method of UserList)
def __lt__(self, other): return self._main.items() < other
+
def __le__(self, other): return self._main.items() <= other
+
def __eq__(self, other): return self._main.items() == other
+
def __ne__(self, other): return self._main.items() != other
+
def __gt__(self, other): return self._main.items() > other
+
def __ge__(self, other): return self._main.items() >= other
+
def __cmp__(self, other): return cmp(self._main.items(), other)
def __contains__(self, item): return item in self._main.items()
+
def __len__(self): return len(self._main._sequence) # easier :-)
+
def __iter__(self): return self._main.iteritems()
+
def count(self, item): return self._main.items().count(item)
+
def index(self, item, *args): return self._main.items().index(item, *args)
+
def reverse(self): self._main.reverse()
+
def sort(self, *args, **kwds): self._main.sort(*args, **kwds)
+
def __mul__(self, n): return self._main.items()*n
__rmul__ = __mul__
+
def __add__(self, other): return self._main.items() + other
+
def __radd__(self, other): return other + self._main.items()
def append(self, item):
@@ -1073,7 +1118,9 @@ class Items(object):
def __imul__(self, n): raise TypeError('Can\'t multiply items in place')
+
class Values(object):
+
"""
Custom object for accessing the values of an OrderedDict.
@@ -1122,17 +1169,27 @@ class Values(object):
# FIXME: do we need to check if we are comparing with another ``Values``
# object? (like the __cast method of UserList)
def __lt__(self, other): return self._main.values() < other
+
def __le__(self, other): return self._main.values() <= other
+
def __eq__(self, other): return self._main.values() == other
+
def __ne__(self, other): return self._main.values() != other
+
def __gt__(self, other): return self._main.values() > other
+
def __ge__(self, other): return self._main.values() >= other
+
def __cmp__(self, other): return cmp(self._main.values(), other)
def __contains__(self, item): return item in self._main.values()
+
def __len__(self): return len(self._main._sequence) # easier :-)
+
def __iter__(self): return self._main.itervalues()
+
def count(self, item): return self._main.values().count(item)
+
def index(self, item, *args): return self._main.values().index(item, *args)
def reverse(self):
@@ -1150,20 +1207,31 @@ class Values(object):
def __mul__(self, n): return self._main.values()*n
__rmul__ = __mul__
+
def __add__(self, other): return self._main.values() + other
+
def __radd__(self, other): return other + self._main.values()
## following methods not implemented for values ##
def __delitem__(self, i): raise TypeError('Can\'t delete items from values')
+
def __iadd__(self, other): raise TypeError('Can\'t add in place to values')
+
def __imul__(self, n): raise TypeError('Can\'t multiply values in place')
+
def append(self, item): raise TypeError('Can\'t append items to values')
+
def insert(self, i, item): raise TypeError('Can\'t insert items into values')
+
def pop(self, i=-1): raise TypeError('Can\'t pop items from values')
+
def remove(self, item): raise TypeError('Can\'t remove items from values')
+
def extend(self, other): raise TypeError('Can\'t extend values')
+
class SequenceOrderedDict(OrderedDict):
+
"""
Experimental version of OrderedDict that has a custom object for ``keys``,
``values``, and ``items``.
diff --git a/git/refs/head.py b/git/refs/head.py
index 1b3e7f00..662c2c87 100644
--- a/git/refs/head.py
+++ b/git/refs/head.py
@@ -10,8 +10,8 @@ from git.exc import GitCommandError
__all__ = ["HEAD", "Head"]
-
class HEAD(SymbolicReference):
+
"""Special case of a Symbolic Reference as it represents the repository's
HEAD reference."""
_HEAD_NAME = 'HEAD'
@@ -92,6 +92,7 @@ class HEAD(SymbolicReference):
class Head(Reference):
+
"""A Head is a named reference to a Commit. Every Head instance contains a name
and a Commit object.
@@ -151,7 +152,6 @@ class Head(Reference):
return self
-
def tracking_branch(self):
"""
:return: The remote_reference we are tracking, or None if we are
diff --git a/git/refs/log.py b/git/refs/log.py
index d5d8d7d4..8917f3fa 100644
--- a/git/refs/log.py
+++ b/git/refs/log.py
@@ -28,6 +28,7 @@ __all__ = ["RefLog", "RefLogEntry"]
class RefLogEntry(tuple):
+
"""Named tuple allowing easy access to the revlog data fields"""
_fmt = "%s %s %s <%s> %i %s\t%s\n"
_re_hexsha_only = re.compile('^[0-9A-Fa-f]{40}$')
@@ -106,6 +107,7 @@ class RefLogEntry(tuple):
class RefLog(list, Serializable):
+
"""A reflog contains reflog entries, each of which defines a certain state
of the head in question. Custom query methods allow to retrieve log entries
by date or by other criteria.
diff --git a/git/refs/reference.py b/git/refs/reference.py
index d8f0c70f..a8ecc95d 100644
--- a/git/refs/reference.py
+++ b/git/refs/reference.py
@@ -12,8 +12,11 @@ from gitdb.util import (
__all__ = ["Reference"]
#{ Utilities
+
+
def require_remote_ref_path(func):
"""A decorator raising a TypeError if we are not a valid remote, based on the path"""
+
def wrapper(self, *args):
if not self.path.startswith(self._remote_common_path_default + "/"):
raise ValueError("ref path does not point to a remote reference: %s" % self.path)
@@ -25,6 +28,7 @@ def require_remote_ref_path(func):
class Reference(SymbolicReference, LazyMixin, Iterable):
+
"""Represents a named reference to any object. Subclasses may apply restrictions though,
i.e. Heads can only point to commits."""
__slots__ = tuple()
@@ -45,7 +49,6 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
raise ValueError("Cannot instantiate %r from path %s" % (self.__class__.__name__, path))
super(Reference, self).__init__(repo, path)
-
def __str__(self):
return self.name
@@ -99,7 +102,6 @@ class Reference(SymbolicReference, LazyMixin, Iterable):
#}END interface
-
#{ Remote Interface
@property
diff --git a/git/refs/remote.py b/git/refs/remote.py
index 4c73b094..6dd0856c 100644
--- a/git/refs/remote.py
+++ b/git/refs/remote.py
@@ -9,10 +9,10 @@ __all__ = ["RemoteReference"]
class RemoteReference(Head):
+
"""Represents a reference pointing to a remote head."""
_common_path_default = Head._remote_common_path_default
-
@classmethod
def iter_items(cls, repo, common_path = None, remote=None):
"""Iterate remote references, and if given, constrain them to the given remote"""
diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py
index 7a4bf59b..6832b8f2 100644
--- a/git/refs/symbolic.py
+++ b/git/refs/symbolic.py
@@ -23,7 +23,9 @@ from log import RefLog
__all__ = ["SymbolicReference"]
+
class SymbolicReference(object):
+
"""Represents a special case of a reference such that this reference is symbolic.
It does not point to a specific commit, but to another Head, which itself
specifies a commit.
@@ -204,7 +206,6 @@ class SymbolicReference(object):
return self
-
def set_object(self, object, logmsg = None):
"""Set the object we point to, possibly dereference our symbolic reference first.
If the reference does not exist, it will be created
@@ -309,7 +310,6 @@ class SymbolicReference(object):
return self
-
# aliased reference
reference = property(_get_reference, set_reference, doc="Returns the Reference we point to")
ref = reference
@@ -441,7 +441,6 @@ class SymbolicReference(object):
os.remove(reflog_path)
#END remove reflog
-
@classmethod
def _create(cls, repo, path, resolve, reference, force, logmsg=None):
"""internal method used to create a new symbolic reference.
diff --git a/git/refs/tag.py b/git/refs/tag.py
index 110fc612..2845ec7c 100644
--- a/git/refs/tag.py
+++ b/git/refs/tag.py
@@ -3,8 +3,8 @@ from reference import Reference
__all__ = ["TagReference", "Tag"]
-
class TagReference(Reference):
+
"""Class representing a lightweight tag reference which either points to a commit
,a tag object or any other object. In the latter case additional information,
like the signature or the tag-creator, is available.
@@ -86,6 +86,5 @@ class TagReference(Reference):
repo.git.tag("-d", *tags)
-
# provide an alias
Tag = TagReference
diff --git a/git/remote.py b/git/remote.py
index 226ee959..7611f743 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -38,6 +38,7 @@ __all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote')
#{ Utilities
+
def digest_process_messages(fh, progress):
"""Read progress messages from file-like object fh, supplying the respective
progress messages to the progress instance.
@@ -61,6 +62,7 @@ def digest_process_messages(fh, progress):
# END while file is not done reading
return dropped_lines
+
def add_progress(kwargs, git, progress):
"""Add the --progress flag to the given kwargs dict if supported by the
git command. If the actual progress in the given progress instance is not
@@ -78,6 +80,7 @@ def add_progress(kwargs, git, progress):
class PushInfo(object):
+
"""
Carries information about the result of a push operation of a single head::
@@ -179,6 +182,7 @@ class PushInfo(object):
class FetchInfo(object):
+
"""
Carries information about the results of a fetch operation of a single head::
@@ -333,6 +337,7 @@ class FetchInfo(object):
class Remote(LazyMixin, Iterable):
+
"""Provides easy read and write access to a git remote.
Everything not part of this interface is considered an option for the current
@@ -385,7 +390,6 @@ class Remote(LazyMixin, Iterable):
else:
super(Remote, self)._set_cache_(attr)
-
def __str__(self):
return self.name
@@ -505,7 +509,6 @@ class Remote(LazyMixin, Iterable):
# skip first line as it is some remote info we are not interested in
output = IterableList('name')
-
# lines which are no progress are fetch info lines
# this also waits for the command to finish
# Skip some progress lines that don't provide relevant information
@@ -559,7 +562,6 @@ class Remote(LazyMixin, Iterable):
finalize_process(proc)
return output
-
def fetch(self, refspec=None, progress=None, **kwargs):
"""Fetch the latest changes for this remote
diff --git a/git/repo/base.py b/git/repo/base.py
index 121624b9..f592f9d7 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -52,6 +52,7 @@ __all__ = ('Repo', )
class Repo(object):
+
"""Represents a git repository and allows you to query references,
gather commit information, generate diffs, create and clone repositories query
the log.
@@ -174,8 +175,6 @@ class Repo(object):
del _get_description
del _set_description
-
-
@property
def working_tree_dir(self):
""":return: The working tree directory of our git repository
diff --git a/git/repo/fun.py b/git/repo/fun.py
index fe26d8ce..15c5762b 100644
--- a/git/repo/fun.py
+++ b/git/repo/fun.py
@@ -15,10 +15,12 @@ from string import digits
__all__ = ('rev_parse', 'is_git_dir', 'touch')
+
def touch(filename):
fp = open(filename, "a")
fp.close()
+
def is_git_dir(d):
""" This is taken from the git setup.c:is_git_directory
function."""
@@ -101,6 +103,7 @@ def name_to_object(repo, name, return_ref=False):
return Object.new_from_sha(repo, hex_to_bin(hexsha))
+
def deref_tag(tag):
"""Recursively dereerence a tag and return the resulting object"""
while True:
@@ -111,6 +114,7 @@ def deref_tag(tag):
# END dereference tag
return tag
+
def to_commit(obj):
"""Convert the given object to a commit if possible and return it"""
if obj.type == 'tag':
@@ -121,6 +125,7 @@ def to_commit(obj):
# END verify type
return obj
+
def rev_parse(repo, rev):
"""
:return: Object at the given revision, either Commit, Tag, Tree or Blob
@@ -170,7 +175,6 @@ def rev_parse(repo, rev):
#END handle ref
# END initialize obj on first token
-
start += 1
# try to parse {type}
@@ -254,7 +258,6 @@ def rev_parse(repo, rev):
# END set default num
# END number parsing only if non-blob mode
-
parsed_to = start
# handle hiererarchy walk
try:
diff --git a/git/test/lib/asserts.py b/git/test/lib/asserts.py
index 52f07eb3..ec3eef96 100644
--- a/git/test/lib/asserts.py
+++ b/git/test/lib/asserts.py
@@ -15,35 +15,43 @@ __all__ = ['assert_instance_of', 'assert_not_instance_of',
'assert_match', 'assert_not_match', 'assert_mode_644',
'assert_mode_755'] + tools.__all__
+
def assert_instance_of(expected, actual, msg=None):
"""Verify that object is an instance of expected """
assert isinstance(actual, expected), msg
+
def assert_not_instance_of(expected, actual, msg=None):
"""Verify that object is not an instance of expected """
assert not isinstance(actual, expected, msg)
+
def assert_none(actual, msg=None):
"""verify that item is None"""
assert actual is None, msg
+
def assert_not_none(actual, msg=None):
"""verify that item is None"""
assert actual is not None, msg
+
def assert_match(pattern, string, msg=None):
"""verify that the pattern matches the string"""
assert_not_none(re.search(pattern, string), msg)
+
def assert_not_match(pattern, string, msg=None):
"""verify that the pattern does not match the string"""
assert_none(re.search(pattern, string), msg)
+
def assert_mode_644(mode):
"""Verify given mode is 644"""
assert (mode & stat.S_IROTH) and (mode & stat.S_IRGRP)
assert (mode & stat.S_IWUSR) and (mode & stat.S_IRUSR) and not (mode & stat.S_IXUSR)
+
def assert_mode_755(mode):
"""Verify given mode is 755"""
assert (mode & stat.S_IROTH) and (mode & stat.S_IRGRP) and (mode & stat.S_IXOTH) and (mode & stat.S_IXGRP)
diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py
index 4f8cdf33..d5045ad7 100644
--- a/git/test/lib/helper.py
+++ b/git/test/lib/helper.py
@@ -21,13 +21,16 @@ __all__ = (
#{ Routines
+
def fixture_path(name):
test_dir = os.path.dirname(os.path.dirname(__file__))
return os.path.join(test_dir, "fixtures", name)
+
def fixture(name):
return open(fixture_path(name), 'rb').read()
+
def absolute_project_path():
return os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
@@ -35,7 +38,9 @@ def absolute_project_path():
#{ Adapters
+
class StringProcessAdapter(object):
+
"""Allows to use strings as Process object as returned by SubProcess.Popen.
Its tailored to work with the test system only"""
@@ -52,6 +57,7 @@ class StringProcessAdapter(object):
#{ Decorators
+
def _mktemp(*args):
"""Wrapper around default tempfile.mktemp to fix an osx issue"""
tdir = tempfile.mktemp(*args)
@@ -59,6 +65,7 @@ def _mktemp(*args):
tdir = '/private' + tdir
return tdir
+
def _rmtree_onerror(osremove, fullpath, exec_info):
"""
Handle the case on windows that read-only files cannot be deleted by
@@ -70,6 +77,7 @@ def _rmtree_onerror(osremove, fullpath, exec_info):
os.chmod(fullpath, 0777)
os.remove(fullpath)
+
def with_rw_repo(working_tree_ref, bare=False):
"""
Same as with_bare_repo, but clones the rorepo as non-bare repository, checking
@@ -81,6 +89,7 @@ def with_rw_repo(working_tree_ref, bare=False):
dir of the repository.
"""
assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout"
+
def argument_passer(func):
def repo_creator(self):
prefix = 'non_'
@@ -117,6 +126,7 @@ def with_rw_repo(working_tree_ref, bare=False):
# END argument passer
return argument_passer
+
def with_rw_and_rw_remote_repo(working_tree_ref):
"""
Same as with_rw_repo, but also provides a writable remote repository from which the
@@ -141,6 +151,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref):
See working dir info in with_rw_repo
"""
assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout"
+
def argument_passer(func):
def remote_repo_creator(self):
remote_repo_dir = _mktemp("remote_repo_%s" % func.__name__)
@@ -208,7 +219,9 @@ def with_rw_and_rw_remote_repo(working_tree_ref):
#} END decorators
+
class TestBase(TestCase):
+
"""
Base Class providing default functionality to all tests such as:
diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py
index acf2e4d5..28500da4 100644
--- a/git/test/performance/lib.py
+++ b/git/test/performance/lib.py
@@ -33,6 +33,7 @@ def resolve_or_fail(env_var):
#{ Base Classes
class TestBigRepoR(TestBase):
+
"""TestCase providing access to readonly 'big' repositories using the following
member variables:
@@ -59,6 +60,7 @@ class TestBigRepoR(TestBase):
class TestBigRepoRW(TestBigRepoR):
+
"""As above, but provides a big repository that we can write to.
Provides ``self.gitrwrepo`` and ``self.puregitrwrepo``"""
diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py
index c3d89931..79555844 100644
--- a/git/test/performance/test_commit.py
+++ b/git/test/performance/test_commit.py
@@ -12,6 +12,7 @@ from cStringIO import StringIO
from time import time
import sys
+
class TestPerformance(TestBigRepoRW):
# ref with about 100 commits in its history
diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py
index cac53a06..c8b59da6 100644
--- a/git/test/performance/test_streams.py
+++ b/git/test/performance/test_streams.py
@@ -44,7 +44,6 @@ class TestObjDBPerformance(TestBigRepoR):
db_file = ldb.readable_db_object_path(bin_to_hex(binsha))
fsize_kib = os.path.getsize(db_file) / 1000
-
size_kib = size / 1000
print >> sys.stderr, "Added %i KiB (filesize = %i KiB) of %s data to loose odb in %f s ( %f Write KiB / s)" % (size_kib, fsize_kib, desc, elapsed_add, size_kib / elapsed_add)
@@ -58,7 +57,6 @@ class TestObjDBPerformance(TestBigRepoR):
assert shadata == stream.getvalue()
print >> sys.stderr, "Read %i KiB of %s data at once from loose odb in %f s ( %f Read KiB / s)" % (size_kib, desc, elapsed_readall, size_kib / elapsed_readall)
-
# reading in chunks of 1 MiB
cs = 512*1000
chunks = list()
@@ -104,7 +102,6 @@ class TestObjDBPerformance(TestBigRepoR):
# compare ...
print >> sys.stderr, "Git-Python is %f %% faster than git when adding big %s files" % (100.0 - (elapsed_add / gelapsed_add) * 100, desc)
-
# read all
st = time()
s, t, size, data = rwrepo.git.get_object_data(gitsha)
@@ -114,7 +111,6 @@ class TestObjDBPerformance(TestBigRepoR):
# compare
print >> sys.stderr, "Git-Python is %f %% faster than git when reading big %sfiles" % (100.0 - (elapsed_readall / gelapsed_readall) * 100, desc)
-
# read chunks
st = time()
s, t, size, stream = rwrepo.git.stream_object_data(gitsha)
diff --git a/git/test/performance/test_utils.py b/git/test/performance/test_utils.py
index 7de77970..4979eaa1 100644
--- a/git/test/performance/test_utils.py
+++ b/git/test/performance/test_utils.py
@@ -14,20 +14,24 @@ class TestUtilPerformance(TestBigRepoR):
# compare dict vs. slot access
class Slotty(object):
__slots__ = "attr"
+
def __init__(self):
self.attr = 1
class Dicty(object):
+
def __init__(self):
self.attr = 1
class BigSlotty(object):
__slots__ = ('attr', ) + tuple('abcdefghijk')
+
def __init__(self):
for attr in self.__slots__:
setattr(self, attr, 1)
class BigDicty(object):
+
def __init__(self):
for attr in BigSlotty.__slots__:
setattr(self, attr, 1)
diff --git a/git/test/test_actor.py b/git/test/test_actor.py
index 06aa1aed..40e307ba 100644
--- a/git/test/test_actor.py
+++ b/git/test/test_actor.py
@@ -8,7 +8,9 @@ import os
from git.test.lib import *
from git import *
+
class TestActor(object):
+
def test_from_string_should_separate_name_and_email(self):
a = Actor._from_string("Michael Trier <mtrier@example.com>")
assert_equal("Michael Trier", a.name)
diff --git a/git/test/test_base.py b/git/test/test_base.py
index d867242c..42b95b39 100644
--- a/git/test/test_base.py
+++ b/git/test/test_base.py
@@ -15,6 +15,7 @@ from git.objects.util import get_object_type_by_name
from gitdb.util import hex_to_bin
import tempfile
+
class TestBase(TestBase):
type_tuples = ( ("blob", "8741fc1d09d61f02ffd8cded15ff603eff1ec070", "blob.py"),
diff --git a/git/test/test_blob.py b/git/test/test_blob.py
index ca78f892..a1d95ac2 100644
--- a/git/test/test_blob.py
+++ b/git/test/test_blob.py
@@ -8,6 +8,7 @@ from git.test.lib import *
from git import *
from gitdb.util import hex_to_bin
+
class TestBlob(TestBase):
def test_mime_type_should_return_mime_type_for_known_types(self):
diff --git a/git/test/test_commit.py b/git/test/test_commit.py
index d6ad3a62..d6e13762 100644
--- a/git/test/test_commit.py
+++ b/git/test/test_commit.py
@@ -82,7 +82,6 @@ class TestCommit(TestBase):
assert isinstance(commit.author_tz_offset, int) and isinstance(commit.committer_tz_offset, int)
assert commit.message == "Added missing information to docstrings of commit and stats module\n"
-
def test_stats(self):
commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781')
stats = commit.stats
diff --git a/git/test/test_config.py b/git/test/test_config.py
index 3884e877..cd1c43ed 100644
--- a/git/test/test_config.py
+++ b/git/test/test_config.py
@@ -10,6 +10,7 @@ import StringIO
from copy import copy
from ConfigParser import NoSectionError
+
class TestBase(TestCase):
def _to_memcache(self, file_path):
diff --git a/git/test/test_db.py b/git/test/test_db.py
index 4bac5647..b53c4209 100644
--- a/git/test/test_db.py
+++ b/git/test/test_db.py
@@ -9,6 +9,7 @@ from gitdb.util import bin_to_hex
from git.exc import BadObject
import os
+
class TestDB(TestBase):
def test_base(self):
diff --git a/git/test/test_diff.py b/git/test/test_diff.py
index a59ee0bf..3c2537da 100644
--- a/git/test/test_diff.py
+++ b/git/test/test_diff.py
@@ -7,6 +7,7 @@
from git.test.lib import *
from git import *
+
class TestDiff(TestBase):
def _assert_diff_format(self, diffs):
diff --git a/git/test/test_fun.py b/git/test/test_fun.py
index 129df3b9..f435f31b 100644
--- a/git/test/test_fun.py
+++ b/git/test/test_fun.py
@@ -23,6 +23,7 @@ from stat import (
from git.index import IndexFile
from cStringIO import StringIO
+
class TestFun(TestBase):
def _assert_index_entries(self, entries, trees):
@@ -78,8 +79,10 @@ class TestFun(TestBase):
def test_three_way_merge(self, rwrepo):
def mkfile(name, sha, executable=0):
return (sha, S_IFREG | 0644 | executable*0111, name)
+
def mkcommit(name, sha):
return (sha, S_IFDIR | S_IFLNK, name)
+
def assert_entries(entries, num_entries, has_conflict=False):
assert len(entries) == num_entries
assert has_conflict == (len([e for e in entries if e.stage != 0]) > 0)
@@ -156,7 +159,6 @@ class TestFun(TestBase):
trees = [tb, th, tm]
assert_entries(aggressive_tree_merge(odb, trees), 3, True)
-
# change mode on same base file, by making one a commit, the other executable
# no content change ( this is totally unlikely to happen in the real world )
fa = mkcommit(bfn, shaa)
diff --git a/git/test/test_git.py b/git/test/test_git.py
index c06b5e24..06410c45 100644
--- a/git/test/test_git.py
+++ b/git/test/test_git.py
@@ -15,6 +15,7 @@ from git.test.lib import ( TestBase,
from git import ( Git,
GitCommandError )
+
class TestGit(TestBase):
@classmethod
@@ -41,7 +42,6 @@ class TestGit(TestBase):
def test_it_raises_errors(self):
self.git.this_does_not_exist()
-
def test_it_transforms_kwargs_into_git_command_arguments(self):
assert_equal(["-s"], self.git.transform_kwargs(**{'s': True}))
assert_equal(["-s5"], self.git.transform_kwargs(**{'s': 5}))
@@ -93,7 +93,6 @@ class TestGit(TestBase):
g.stdin.flush()
assert g.stdout.readline() == obj_info
-
# same can be achived using the respective command functions
hexsha, typename, size = self.git.get_object_header(hexsha)
hexsha, typename_two, size_two, data = self.git.get_object_data(hexsha)
diff --git a/git/test/test_index.py b/git/test/test_index.py
index 9d75da53..b902f4d5 100644
--- a/git/test/test_index.py
+++ b/git/test/test_index.py
@@ -14,6 +14,7 @@ import glob
import shutil
from stat import *
+
class TestIndex(TestBase):
def __init__(self, *args):
@@ -122,7 +123,6 @@ class TestIndex(TestBase):
three_way_index = IndexFile.from_tree(rw_repo, common_ancestor_sha, cur_sha, other_sha)
assert len(list(e for e in three_way_index.entries.values() if e.stage != 0))
-
# ITERATE BLOBS
merge_required = lambda t: t[0] != 0
merge_blobs = list(three_way_index.iter_blobs(merge_required))
@@ -135,7 +135,6 @@ class TestIndex(TestBase):
for stage, blob in base_index.iter_blobs(BlobFilter([prefix])):
assert blob.path.startswith(prefix)
-
# writing a tree should fail with an unmerged index
self.failUnlessRaises(UnmergedEntriesError, three_way_index.write_tree)
@@ -213,7 +212,6 @@ class TestIndex(TestBase):
unmerged_blobs = unmerged_tree.unmerged_blobs()
assert len(unmerged_blobs) == 1 and unmerged_blobs.keys()[0] == manifest_key[0]
-
@with_rw_repo('0.1.6')
def test_index_file_diffing(self, rw_repo):
# default Index instance points to our index
@@ -572,10 +570,10 @@ class TestIndex(TestBase):
rval = index.move(['doc', 'test'])
assert_mv_rval(rval)
-
# TEST PATH REWRITING
######################
count = [0]
+
def rewriter(entry):
rval = str(count[0])
count[0] += 1
@@ -601,7 +599,6 @@ class TestIndex(TestBase):
for filenum in range(len(paths)):
assert index.entry_key(str(filenum), 0) in index.entries
-
# TEST RESET ON PATHS
######################
arela = "aa"
@@ -640,7 +637,6 @@ class TestIndex(TestBase):
for absfile in absfiles:
assert os.path.isfile(absfile)
-
@with_rw_repo('HEAD')
def test_compare_write_tree(self, rw_repo):
# write all trees and compare them
diff --git a/git/test/test_reflog.py b/git/test/test_reflog.py
index ba3a531b..76cfd870 100644
--- a/git/test/test_reflog.py
+++ b/git/test/test_reflog.py
@@ -7,6 +7,7 @@ import tempfile
import shutil
import os
+
class TestRefLog(TestBase):
def test_reflogentry(self):
@@ -95,6 +96,5 @@ class TestRefLog(TestBase):
#END for each index to read
# END for each reflog
-
# finally remove our temporary data
shutil.rmtree(tdir)
diff --git a/git/test/test_refs.py b/git/test/test_refs.py
index 5eb214ba..fc58dafa 100644
--- a/git/test/test_refs.py
+++ b/git/test/test_refs.py
@@ -13,6 +13,7 @@ from git.objects.tag import TagObject
from itertools import chain
import os
+
class TestRefs(TestBase):
def test_from_path(self):
@@ -55,7 +56,6 @@ class TestRefs(TestBase):
assert tag_object_refs
assert isinstance(self.rorepo.tags['0.1.5'], TagReference)
-
def test_tags_author(self):
tag = self.rorepo.tags[0]
tagobj = tag.tag
@@ -63,8 +63,6 @@ class TestRefs(TestBase):
tagger_name = tagobj.tagger.name
assert tagger_name == 'Michael Trier'
-
-
def test_tags(self):
# tag refs can point to tag objects or to commits
s = set()
@@ -138,7 +136,6 @@ class TestRefs(TestBase):
assert len(cur_head.log()) == blog_len+1
assert len(head.log()) == hlog_len+3
-
# with automatic dereferencing
assert head.set_commit(cur_commit, 'change commit once again') is head
assert len(head.log()) == hlog_len+4
@@ -151,7 +148,6 @@ class TestRefs(TestBase):
assert log[0].oldhexsha == pcommit.NULL_HEX_SHA
assert log[0].newhexsha == pcommit.hexsha
-
def test_refs(self):
types_found = set()
for ref in self.rorepo.refs:
@@ -191,7 +187,6 @@ class TestRefs(TestBase):
cur_head.reset(new_head_commit)
rw_repo.index.checkout(["lib"], force=True)#
-
# now that we have a write write repo, change the HEAD reference - its
# like git-reset --soft
heads = rw_repo.heads
@@ -499,7 +494,6 @@ class TestRefs(TestBase):
refs = list(SymbolicReference.iter_items(rw_repo))
assert len(refs) == 1
-
# test creation of new refs from scratch
for path in ("basename", "dir/somename", "dir2/subdir/basename"):
# REFERENCES
diff --git a/git/test/test_remote.py b/git/test/test_remote.py
index 0b7ab574..19d029e5 100644
--- a/git/test/test_remote.py
+++ b/git/test/test_remote.py
@@ -15,8 +15,10 @@ import random
# assure we have repeatable results
random.seed(0)
+
class TestRemoteProgress(RemoteProgress):
__slots__ = ( "_seen_lines", "_stages_per_op", '_num_progress_messages' )
+
def __init__(self):
super(TestRemoteProgress, self).__init__()
self._seen_lines = list()
@@ -51,7 +53,6 @@ class TestRemoteProgress(RemoteProgress):
self._num_progress_messages += 1
-
def make_assertion(self):
# we don't always receive messages
if not self._seen_lines:
@@ -76,7 +77,6 @@ class TestRemote(TestBase):
fp = open(os.path.join(repo.git_dir, "FETCH_HEAD"))
fp.close()
-
def _do_test_fetch_result(self, results, remote):
# self._print_fetchhead(remote.repo)
assert len(results) > 0 and isinstance(results[0], FetchInfo)
@@ -116,7 +116,6 @@ class TestRemote(TestBase):
# END error checking
# END for each info
-
def _do_test_fetch_info(self, repo):
self.failUnlessRaises(ValueError, FetchInfo._from_line, repo, "nonsense", '')
self.failUnlessRaises(ValueError, FetchInfo._from_line, repo, "? [up to date] 0.1.7RC -> origin/0.1.7RC", '')
diff --git a/git/test/test_repo.py b/git/test/test_repo.py
index 1ecd2ae4..38c03b7a 100644
--- a/git/test/test_repo.py
+++ b/git/test/test_repo.py
@@ -103,7 +103,6 @@ class TestRepo(TestBase):
# END for each tree
assert num_trees == mc
-
def _assert_empty_repo(self, repo):
# test all kinds of things with an empty, freshly initialized repo.
# It should throw good errors
@@ -131,7 +130,6 @@ class TestRepo(TestBase):
pass
# END test repos with working tree
-
def test_init(self):
prev_cwd = os.getcwd()
os.chdir(tempfile.gettempdir())
@@ -153,7 +151,6 @@ class TestRepo(TestBase):
rc = r.clone(clone_path)
self._assert_empty_repo(rc)
-
try:
shutil.rmtree(clone_path)
except OSError:
@@ -362,6 +359,7 @@ class TestRepo(TestBase):
return Git.CatFileContentStream(len(d)-1, StringIO(d))
ts = 5
+
def mktiny():
return Git.CatFileContentStream(ts, StringIO(d))
@@ -434,7 +432,6 @@ class TestRepo(TestBase):
assert obj.type == 'blob' and obj.path == 'CHANGES'
assert rev_obj.tree['CHANGES'] == obj
-
def _assert_rev_parse(self, name):
"""tries multiple different rev-parse syntaxes with the given name
:return: parsed object"""
@@ -521,13 +518,11 @@ class TestRepo(TestBase):
assert tag.object == rev_parse(tag.object.hexsha)
self._assert_rev_parse_types(tag.object.hexsha, tag.object)
-
# multiple tree types result in the same tree: HEAD^{tree}^{tree}:CHANGES
rev = '0.1.4^{tree}^{tree}'
assert rev_parse(rev) == tag.object.tree
assert rev_parse(rev+':CHANGES') == tag.object.tree['CHANGES']
-
# try to get parents from first revision - it should fail as no such revision
# exists
first_rev = "33ebe7acec14b25c5f84f35a664803fcab2f7781"
@@ -543,11 +538,9 @@ class TestRepo(TestBase):
commit2 = rev_parse(first_rev[:5])
assert commit2 == commit
-
# todo: dereference tag into a blob 0.1.7^{blob} - quite a special one
# needs a tag which points to a blob
-
# ref^0 returns commit being pointed to, same with ref~0, and ^{}
tag = rev_parse('0.1.4')
for token in (('~0', '^0', '^{}')):
diff --git a/git/test/test_stats.py b/git/test/test_stats.py
index ede73153..d827c680 100644
--- a/git/test/test_stats.py
+++ b/git/test/test_stats.py
@@ -7,6 +7,7 @@
from git.test.lib import *
from git import *
+
class TestStats(TestBase):
def test__list_from_string(self):
diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py
index 827705cf..0cf620c1 100644
--- a/git/test/test_submodule.py
+++ b/git/test/test_submodule.py
@@ -25,6 +25,7 @@ if sys.platform == 'win32':
class TestRootProgress(RootUpdateProgress):
+
"""Just prints messages, for now without checking the correctness of the states"""
def update(self, op, index, max_count, message=''):
@@ -32,13 +33,13 @@ class TestRootProgress(RootUpdateProgress):
prog = TestRootProgress()
+
class TestSubmodule(TestBase):
k_subm_current = "468cad66ff1f80ddaeee4123c24e4d53a032c00d"
k_subm_changed = "394ed7006ee5dc8bddfd132b64001d5dfc0ffdd3"
k_no_subm_tag = "0.1.6"
-
def _do_base_tests(self, rwrepo):
"""Perform all tests in the given repository, it may be bare or nonbare"""
# manual instantiation
@@ -168,7 +169,6 @@ class TestSubmodule(TestBase):
# or we raise
self.failUnlessRaises(ValueError, Submodule.add, rwrepo, "newsubm", sm.path, "git://someurl/repo.git")
-
# CONTINUE UPDATE
#################
# we should have setup a tracking branch, which is also active
@@ -208,7 +208,6 @@ class TestSubmodule(TestBase):
# this flushed in a sub-submodule
assert len(list(rwrepo.iter_submodules())) == 2
-
# reset both heads to the previous version, verify that to_latest_revision works
smods = (sm.module(), csm.module())
for repo in smods:
@@ -469,7 +468,6 @@ class TestSubmodule(TestBase):
nsm.remove(configuration=False, module=True)
assert not nsm.module_exists() and nsm.exists()
-
# dry-run does nothing
rm.update(recursive=False, dry_run=True, progress=prog)
@@ -477,8 +475,6 @@ class TestSubmodule(TestBase):
rm.update(recursive=False, progress=prog)
assert nsm.module_exists()
-
-
# remove submodule - the previous one
#====================================
sm.set_parent_commit(csmadded)
@@ -495,7 +491,6 @@ class TestSubmodule(TestBase):
rm.update(recursive=False)
assert not os.path.isdir(smp)
-
# change url
#=============
# to the first repository, this way we have a fast checkout, and a completely different
diff --git a/git/test/test_tree.py b/git/test/test_tree.py
index 982fa2e1..7edae577 100644
--- a/git/test/test_tree.py
+++ b/git/test/test_tree.py
@@ -13,6 +13,7 @@ from git.objects.fun import (
)
from cStringIO import StringIO
+
class TestTree(TestBase):
def test_serializable(self):
@@ -38,7 +39,6 @@ class TestTree(TestBase):
testtree._deserialize(stream)
assert testtree._cache == orig_cache
-
# TEST CACHE MUTATOR
mod = testtree.cache
self.failUnlessRaises(ValueError, mod.add, "invalid sha", 0, "name")
diff --git a/git/test/test_util.py b/git/test/test_util.py
index acca0928..ea62425b 100644
--- a/git/test/test_util.py
+++ b/git/test/test_util.py
@@ -17,6 +17,7 @@ import time
class TestIterableMember(object):
+
"""A member of an iterable list"""
__slots__ = ("name", "prefix_name")
@@ -26,6 +27,7 @@ class TestIterableMember(object):
class TestUtils(TestBase):
+
def setup(self):
self.testdict = {
"string": "42",
@@ -37,7 +39,6 @@ class TestUtils(TestBase):
assert_equal('this-is-my-argument', dashify('this_is_my_argument'))
assert_equal('foo', dashify('foo'))
-
def test_lock_file(self):
my_file = tempfile.mktemp()
lock_file = LockFile(my_file)
diff --git a/git/util.py b/git/util.py
index ba5d3b9f..8d5cd765 100644
--- a/git/util.py
+++ b/git/util.py
@@ -33,6 +33,7 @@ __all__ = ( "stream_copy", "join_path", "to_native_path_windows", "to_native_pat
#{ Utility Methods
+
def rmtree(path):
"""Remove the given recursively.
:note: we use shutil rmtree but adjust its behaviour to see whether files that
@@ -48,7 +49,6 @@ def rmtree(path):
return shutil.rmtree(path, False, onerror)
-
def stream_copy(source, destination, chunk_size=512*1024):
"""Copy all data from the source stream into the destination stream in chunks
of size chunk_size
@@ -64,6 +64,7 @@ def stream_copy(source, destination, chunk_size=512*1024):
# END reading output stream
return br
+
def join_path(a, *p):
"""Join path tokens together similar to os.path.join, but always use
'/' instead of possibly '\' on windows."""
@@ -80,9 +81,11 @@ def join_path(a, *p):
# END for each path token to add
return path
+
def to_native_path_windows(path):
return path.replace('/','\\')
+
def to_native_path_linux(path):
return path.replace('\\','/')
@@ -94,6 +97,7 @@ else:
return path
to_native_path = to_native_path_linux
+
def join_path_native(a, *p):
"""
As join path, but makes sure an OS native path is returned. This is only
@@ -101,6 +105,7 @@ def join_path_native(a, *p):
use '\'"""
return to_native_path(join_path(a, *p))
+
def assure_directory_exists(path, is_file=False):
"""Assure that the directory pointed to by path exists.
@@ -115,10 +120,12 @@ def assure_directory_exists(path, is_file=False):
return True
return False
+
def get_user_id():
""":return: string identifying the currently active system user as name@node"""
return "%s@%s" % (getpass.getuser(), platform.node())
+
def finalize_process(proc):
"""Wait for the process (clone, fetch, pull or push) and handle its errors accordingly"""
try:
@@ -135,7 +142,9 @@ def finalize_process(proc):
#{ Classes
+
class RemoteProgress(object):
+
"""
Handler providing an interface to parse progress information emitted by git-push
and git-fetch and to dispatch callbacks allowing subclasses to react to the progress.
@@ -270,6 +279,7 @@ class RemoteProgress(object):
class Actor(object):
+
"""Actors hold information about a person acting on the repository. They
can be committers and authors or anything with a name and an email as
mentioned in the git log entries."""
@@ -351,7 +361,6 @@ class Actor(object):
#END for each item to retrieve
return actor
-
@classmethod
def committer(cls, config_reader=None):
"""
@@ -369,7 +378,9 @@ class Actor(object):
but defaults to the committer"""
return cls._main_actor(cls.env_author_name, cls.env_author_email, config_reader)
+
class Stats(object):
+
"""
Represents stat information as presented by git at the end of a merge. It is
created from the output of a diff operation.
@@ -421,6 +432,7 @@ class Stats(object):
class IndexFileSHA1Writer(object):
+
"""Wrapper around a file-like object that remembers the SHA1 of
the data written to it. It will write a sha when the stream is closed
or if the asked for explicitly usign write_sha.
@@ -453,6 +465,7 @@ class IndexFileSHA1Writer(object):
class LockFile(object):
+
"""Provides methods to obtain, check for, and release a file based lock which
should be used to handle concurrent access to the same file.
@@ -524,6 +537,7 @@ class LockFile(object):
class BlockingLockFile(LockFile):
+
"""The lock file will block until a lock could be obtained, or fail after
a specified timeout.
@@ -531,6 +545,7 @@ class BlockingLockFile(LockFile):
be raised during the blocking period, preventing hangs as the lock
can never be obtained."""
__slots__ = ("_check_interval", "_max_block_time")
+
def __init__(self, file_path, check_interval_s=0.3, max_block_time_s=sys.maxint):
"""Configure the instance
@@ -572,6 +587,7 @@ class BlockingLockFile(LockFile):
class IterableList(list):
+
"""
List of iterable objects allowing to query an object by id or by named index::
@@ -647,6 +663,7 @@ class IterableList(list):
class Iterable(object):
+
"""Defines an interface for iterable items which is to assure a uniform
way to retrieve and iterate items within the git repository"""
__slots__ = tuple()
@@ -666,7 +683,6 @@ class Iterable(object):
out_list.extend(cls.iter_items(repo, *args, **kwargs))
return out_list
-
@classmethod
def iter_items(cls, repo, *args, **kwargs):
"""For more information about the arguments, see list_items