diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2011-04-29 17:04:37 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2011-04-29 17:04:37 +0200 |
commit | 3fe1a7f87d511758adf2e56803cb3610b80c5f08 (patch) | |
tree | 3808cf15466a528ee3f266eb714f380aba2d9a7f | |
parent | a80f9af7d3d18a657111061dcc1104d7a8aec64b (diff) | |
download | gitpython-3fe1a7f87d511758adf2e56803cb3610b80c5f08.tar.gz |
Moved rev_parse code into gitdb, this probably broke pretty much here, which is still to be fixed of course
-rw-r--r-- | doc/source/changes.rst | 3 | ||||
m--------- | git/ext/gitdb | 0 | ||||
-rw-r--r-- | git/refs/head.py | 7 | ||||
-rw-r--r-- | git/refs/reference.py | 3 | ||||
-rw-r--r-- | git/refs/remote.py | 3 | ||||
-rw-r--r-- | git/refs/symbolic.py | 3 | ||||
-rw-r--r-- | git/refs/tag.py | 1 | ||||
-rw-r--r-- | git/repo/base.py | 35 | ||||
-rw-r--r-- | git/repo/fun.py | 278 | ||||
-rw-r--r-- | git/util.py | 19 |
10 files changed, 20 insertions, 332 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst index f6151968..da349c50 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -9,6 +9,9 @@ NEXT * object_binsha property added * Blob Type * Added mode constants to ease the manual creation of blobs + +* ### Module Changes ### + * Removed rev_parse function from git.repo.fun - the respective functionality is available only through the repository's rev_parse method, which might in turn translate to any implementation. 0.3.1 Beta 2 ============ diff --git a/git/ext/gitdb b/git/ext/gitdb -Subproject a6778e0dde176b87ebad124837b508a5d7bb125 +Subproject e24994109f01bd315fd6a2aaecbbfcdd05bd058 diff --git a/git/refs/head.py b/git/refs/head.py index dec03551..8ebb409c 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -1,13 +1,12 @@ from gitdb.ref.head import HEAD as GitDB_HEAD -from gitdb.ref.head import Head as GitDB_Head +from gitdb.ref.headref import Head as GitDB_Head from git.exc import GitCommandError -from git.util import RepoAliasMixin __all__ = ["HEAD", "Head"] -class HEAD(GitDB_HEAD, RepoAliasMixin): +class HEAD(GitDB_HEAD): """Provides additional functionality using the git command""" __slots__ = tuple() @@ -73,7 +72,7 @@ class HEAD(GitDB_HEAD, RepoAliasMixin): return self -class Head(GitDB_Head, RepoAliasMixin): +class Head(GitDB_Head): """The GitPyhton Head implementation provides more git-command based features A Head is a named reference to a Commit. Every Head instance contains a name diff --git a/git/refs/reference.py b/git/refs/reference.py index 135277e6..cead66ce 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -1,8 +1,7 @@ from gitdb.ref.reference import Reference as GitDB_Reference -from git.util import RepoAliasMixin __all__ = ["Reference"] -class Reference(GitDB_Reference, RepoAliasMixin): +class Reference(GitDB_Reference): __slots__ = tuple() pass diff --git a/git/refs/remote.py b/git/refs/remote.py index ae6f626d..04d0d5dd 100644 --- a/git/refs/remote.py +++ b/git/refs/remote.py @@ -1,11 +1,10 @@ import os from gitdb.ref.remote import RemoteReference as GitDB_RemoteReference -from git.util import RepoAliasMixin __all__ = ["RemoteReference"] -class RemoteReference(GitDB_RemoteReference, RepoAliasMixin): +class RemoteReference(GitDB_RemoteReference): """Represents a reference pointing to a remote head.""" __slots__ = tuple() diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 9232c49c..90bfaec2 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -1,7 +1,6 @@ from gitdb.ref.symbolic import SymbolicReference as GitDB_SymbolicReference -from git.util import RepoAliasMixin __all__ = ["SymbolicReference"] -class SymbolicReference(GitDB_SymbolicReference, RepoAliasMixin): +class SymbolicReference(GitDB_SymbolicReference): __slots__ = tuple() pass diff --git a/git/refs/tag.py b/git/refs/tag.py index 8ba9ba84..7bcff886 100644 --- a/git/refs/tag.py +++ b/git/refs/tag.py @@ -1,5 +1,4 @@ from gitdb.ref.tag import TagReference as GitDB_TagReference -from git.util import RepoAliasMixin __all__ = ["TagReference", "Tag"] diff --git a/git/repo/base.py b/git/repo/base.py index 0405a5f9..b8509aa7 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -25,7 +25,6 @@ from gitdb.util import ( ) from fun import ( - rev_parse, is_git_dir, touch ) @@ -67,10 +66,6 @@ class Repo(object): re_author_committer_start = re.compile(r'^(author|committer)') re_tab_full_line = re.compile(r'^\t(.*)$') - # invariants - # represents the configuration level of a configuration file - config_level = ("system", "global", "repository") - def __init__(self, path=None, odbt = DefaultDBType): """Create a new Repo instance @@ -167,6 +162,9 @@ class Repo(object): del _set_description + @property + def config_level(self): + return self.odb.config_level @property def working_tree_dir(self): @@ -311,21 +309,6 @@ class Repo(object): """Delete the given remote.""" return Remote.remove(self, remote) - def _get_config_path(self, config_level ): - # we do not support an absolute path of the gitconfig on windows , - # use the global config instead - if sys.platform == "win32" and config_level == "system": - config_level = "global" - - if config_level == "system": - return "/etc/gitconfig" - elif config_level == "global": - return os.path.normpath(os.path.expanduser("~/.gitconfig")) - elif config_level == "repository": - return join(self.git_dir, "config") - - raise ValueError( "Invalid configuration level: %r" % config_level ) - def config_reader(self, config_level=None): """ :return: @@ -341,12 +324,7 @@ class Repo(object): instance :note: On windows, system configuration cannot currently be read as the path is unknown, instead the global path will be used.""" - files = None - if config_level is None: - files = [ self._get_config_path(f) for f in self.config_level ] - else: - files = [ self._get_config_path(config_level) ] - return GitConfigParser(files, read_only=True) + return self.odb.config_reader(config_level) def config_writer(self, config_level="repository"): """ @@ -361,7 +339,7 @@ class Repo(object): system = sytem wide configuration file global = user level configuration file repository = configuration file for this repostory only""" - return GitConfigParser(self._get_config_path(config_level), read_only = False) + return self.odb.config_writer(config_level) def commit(self, rev=None): """The Commit object for the specified revision @@ -747,7 +725,8 @@ class Repo(object): self.git.archive(treeish, **kwargs) return self - rev_parse = rev_parse + def rev_parse(self, name): + return self.odb.rev_parse(name) def __repr__(self): return '<git.Repo "%s">' % self.git_dir diff --git a/git/repo/fun.py b/git/repo/fun.py index 03d55716..7529897d 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -1,284 +1,10 @@ """Package with general repository related functions""" import os -from gitdb.exc import BadObject -from git.refs import SymbolicReference -from git.objects import Object -from gitdb.util import ( - join, - isdir, - isfile, - hex_to_bin, - bin_to_hex - ) -from string import digits +from gitdb.util import is_git_dir -__all__ = ('rev_parse', 'is_git_dir', 'touch') +__all__ = ('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.""" - if isdir(d) and \ - isdir(join(d, 'objects')) and \ - isdir(join(d, 'refs')): - headref = join(d, 'HEAD') - return isfile(headref) or \ - (os.path.islink(headref) and - os.readlink(headref).startswith('refs')) - return False - - -def short_to_long(odb, hexsha): - """:return: long hexadecimal sha1 from the given less-than-40 byte hexsha - or None if no candidate could be found. - :param hexsha: hexsha with less than 40 byte""" - try: - return bin_to_hex(odb.partial_to_complete_sha_hex(hexsha)) - except BadObject: - return None - # END exception handling - - -def name_to_object(repo, name, return_ref=False): - """ - :return: object specified by the given name, hexshas ( short and long ) - as well as references are supported - :param return_ref: if name specifies a reference, we will return the reference - instead of the object. Otherwise it will raise BadObject - """ - hexsha = None - - # is it a hexsha ? Try the most common ones, which is 7 to 40 - if repo.re_hexsha_shortened.match(name): - if len(name) != 40: - # find long sha for short sha - hexsha = short_to_long(repo.odb, name) - else: - hexsha = name - # END handle short shas - #END find sha if it matches - - # if we couldn't find an object for what seemed to be a short hexsha - # try to find it as reference anyway, it could be named 'aaa' for instance - if hexsha is None: - for base in ('%s', 'refs/%s', 'refs/tags/%s', 'refs/heads/%s', 'refs/remotes/%s', 'refs/remotes/%s/HEAD'): - try: - hexsha = SymbolicReference.dereference_recursive(repo, base % name) - if return_ref: - return SymbolicReference(repo, base % name) - #END handle symbolic ref - break - except ValueError: - pass - # END for each base - # END handle hexsha - - # didn't find any ref, this is an error - if return_ref: - raise BadObject("Couldn't find reference named %r" % name) - #END handle return ref - - # tried everything ? fail - if hexsha is None: - raise BadObject(name) - # END assert hexsha was found - - 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: - try: - tag = tag.object - except AttributeError: - break - # 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': - obj = deref_tag(obj) - - if obj.type != "commit": - raise ValueError("Cannot convert object %r to type commit" % obj) - # END verify type - return obj - -def rev_parse(repo, rev): - """ - :return: Object at the given revision, either Commit, Tag, Tree or Blob - :param rev: git-rev-parse compatible revision specification, please see - http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html - for details - :note: Currently there is no access to the rev-log, rev-specs may only contain - topological tokens such ~ and ^. - :raise BadObject: if the given revision could not be found - :raise ValueError: If rev couldn't be parsed - :raise IndexError: If invalid reflog index is specified""" - - # colon search mode ? - if rev.startswith(':/'): - # colon search mode - raise NotImplementedError("commit by message search ( regex )") - # END handle search - - obj = None - ref = None - output_type = "commit" - start = 0 - parsed_to = 0 - lr = len(rev) - while start < lr: - if rev[start] not in "^~:@": - start += 1 - continue - # END handle start - - token = rev[start] - - if obj is None: - # token is a rev name - if start == 0: - ref = repo.head.ref - else: - if token == '@': - ref = name_to_object(repo, rev[:start], return_ref=True) - else: - obj = name_to_object(repo, rev[:start]) - #END handle token - #END handle refname - - if ref is not None: - obj = ref.commit - #END handle ref - # END initialize obj on first token - - - start += 1 - - # try to parse {type} - if start < lr and rev[start] == '{': - end = rev.find('}', start) - if end == -1: - raise ValueError("Missing closing brace to define type in %s" % rev) - output_type = rev[start+1:end] # exclude brace - - # handle type - if output_type == 'commit': - pass # default - elif output_type == 'tree': - try: - obj = to_commit(obj).tree - except (AttributeError, ValueError): - pass # error raised later - # END exception handling - elif output_type in ('', 'blob'): - if obj.type == 'tag': - obj = deref_tag(obj) - else: - # cannot do anything for non-tags - pass - # END handle tag - elif token == '@': - # try single int - assert ref is not None, "Requre Reference to access reflog" - revlog_index = None - try: - # transform reversed index into the format of our revlog - revlog_index = -(int(output_type)+1) - except ValueError: - # TODO: Try to parse the other date options, using parse_date - # maybe - raise NotImplementedError("Support for additional @{...} modes not implemented") - #END handle revlog index - - try: - entry = ref.log_entry(revlog_index) - except IndexError: - raise IndexError("Invalid revlog index: %i" % revlog_index) - #END handle index out of bound - - obj = Object.new_from_sha(repo, hex_to_bin(entry.newhexsha)) - - # make it pass the following checks - output_type = None - else: - raise ValueError("Invalid output type: %s ( in %s )" % (output_type, rev)) - # END handle output type - - # empty output types don't require any specific type, its just about dereferencing tags - if output_type and obj.type != output_type: - raise ValueError("Could not accomodate requested object type %r, got %s" % (output_type, obj.type)) - # END verify ouput type - - start = end+1 # skip brace - parsed_to = start - continue - # END parse type - - # try to parse a number - num = 0 - if token != ":": - found_digit = False - while start < lr: - if rev[start] in digits: - num = num * 10 + int(rev[start]) - start += 1 - found_digit = True - else: - break - # END handle number - # END number parse loop - - # no explicit number given, 1 is the default - # It could be 0 though - if not found_digit: - num = 1 - # END set default num - # END number parsing only if non-blob mode - - - parsed_to = start - # handle hiererarchy walk - try: - if token == "~": - obj = to_commit(obj) - for item in xrange(num): - obj = obj.parents[0] - # END for each history item to walk - elif token == "^": - obj = to_commit(obj) - # must be n'th parent - if num: - obj = obj.parents[num-1] - elif token == ":": - if obj.type != "tree": - obj = obj.tree - # END get tree type - obj = obj[rev[start:]] - parsed_to = lr - else: - raise ValueError("Invalid token: %r" % token) - # END end handle tag - except (IndexError, AttributeError): - raise BadObject("Invalid Revision in %s" % rev) - # END exception handling - # END parse loop - - # still no obj ? Its probably a simple name - if obj is None: - obj = name_to_object(repo, rev) - parsed_to = lr - # END handle simple name - - if obj is None: - raise ValueError("Revision specifier could not be parsed: %s" % rev) - - if parsed_to != lr: - raise ValueError("Didn't consume complete rev spec %s, consumed part: %s" % (rev, rev[:parsed_to])) - - return obj diff --git a/git/util.py b/git/util.py index 3d9fd7d5..a1d0cb12 100644 --- a/git/util.py +++ b/git/util.py @@ -9,7 +9,6 @@ import re import sys import time import tempfile -import platform from gitdb.util import ( make_sha, @@ -28,7 +27,8 @@ from gitdb.util import ( Actor, Iterable, stream_copy, - IterableList + IterableList, + get_user_id ) __all__ = ( "stream_copy", "join_path", "to_native_path_windows", "to_native_path_linux", @@ -36,21 +36,6 @@ __all__ = ( "stream_copy", "join_path", "to_native_path_windows", "to_native_pat "BlockingLockFile", "LockFile", 'Actor', 'get_user_id', 'assure_directory_exists', 'RemoteProgress', 'RepoAliasMixin') -#{ Utility Methods - - -def get_user_id(): - """:return: string identifying the currently active system user as name@node - :note: user can be set with the 'USER' environment variable, usually set on windows""" - ukn = 'UNKNOWN' - username = os.environ.get('USER', os.environ.get('USERNAME', ukn)) - if username == ukn and hasattr(os, 'getlogin'): - username = os.getlogin() - # END get username from login - return "%s@%s" % (username, platform.node()) - -#} END utilities - #{ Classes class RemoteProgress(object): |