summaryrefslogtreecommitdiff
path: root/git/db/py/resolve.py
diff options
context:
space:
mode:
Diffstat (limited to 'git/db/py/resolve.py')
-rw-r--r--git/db/py/resolve.py162
1 files changed, 82 insertions, 80 deletions
diff --git a/git/db/py/resolve.py b/git/db/py/resolve.py
index 8a64d76b..4301c2ad 100644
--- a/git/db/py/resolve.py
+++ b/git/db/py/resolve.py
@@ -4,12 +4,12 @@ version assuming compatible interface for reference and object types"""
from git.db.interface import ReferencesMixin
from git.exc import BadObject
from git.refs import (
- SymbolicReference,
- Reference,
- HEAD,
- Head,
- TagReference
- )
+ SymbolicReference,
+ Reference,
+ HEAD,
+ Head,
+ TagReference
+)
from git.refs.head import HEAD
from git.refs.headref import Head
from git.refs.tag import TagReference
@@ -17,13 +17,13 @@ from git.refs.tag import TagReference
from git.objects.base import Object
from git.objects.commit import Commit
from git.util import (
- join,
- isdir,
- isfile,
- hex_to_bin,
- bin_to_hex,
- is_git_dir
- )
+ join,
+ isdir,
+ isfile,
+ hex_to_bin,
+ bin_to_hex,
+ is_git_dir
+)
from string import digits
import os
import re
@@ -32,6 +32,7 @@ __all__ = ["PureReferencesMixin"]
#{ Utilities
+
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.
@@ -41,8 +42,8 @@ def short_to_long(odb, 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 )
@@ -51,7 +52,7 @@ def name_to_object(repo, name, return_ref=False):
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:
@@ -60,9 +61,9 @@ def name_to_object(repo, name, return_ref=False):
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
+ # 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'):
@@ -70,7 +71,7 @@ def name_to_object(repo, name, return_ref=False):
hexsha = SymbolicReference.dereference_recursive(repo, base % name)
if return_ref:
return SymbolicReference(repo, base % name)
- #END handle symbolic ref
+ # END handle symbolic ref
break
except ValueError:
pass
@@ -80,15 +81,16 @@ def name_to_object(repo, name, return_ref=False):
# 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
+ # 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 dereference a tag and return the resulting object"""
while True:
@@ -99,16 +101,18 @@ 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':
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
@@ -120,13 +124,13 @@ def rev_parse(repo, rev):
: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"
@@ -138,9 +142,9 @@ def rev_parse(repo, rev):
start += 1
continue
# END handle start
-
+
token = rev[start]
-
+
if obj is None:
# token is a rev name
if start == 0:
@@ -150,27 +154,26 @@ def rev_parse(repo, rev):
ref = name_to_object(repo, rev[:start], return_ref=True)
else:
obj = name_to_object(repo, rev[:start])
- #END handle token
- #END handle refname
-
+ # END handle token
+ # END handle refname
+
if ref is not None:
obj = ref.commit
- #END handle ref
+ # 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
+ output_type = rev[start + 1:end] # exclude brace
+
+ # handle type
if output_type == 'commit':
- pass # default
+ pass # default
elif output_type == 'tree':
try:
obj = to_commit(obj).tree
@@ -190,37 +193,37 @@ def rev_parse(repo, rev):
revlog_index = None
try:
# transform reversed index into the format of our revlog
- revlog_index = -(int(output_type)+1)
+ 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
-
+ # 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
-
+ # 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))
+ 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
+
+ start = end + 1 # skip brace
parsed_to = start
continue
# END parse type
-
+
# try to parse a number
num = 0
if token != ":":
@@ -234,15 +237,14 @@ def rev_parse(repo, rev):
break
# END handle number
# END number parse loop
-
+
# no explicit number given, 1 is the default
- # It could be 0 though
+ # 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:
@@ -255,7 +257,7 @@ def rev_parse(repo, rev):
obj = to_commit(obj)
# must be n'th parent
if num:
- obj = obj.parents[num-1]
+ obj = obj.parents[num - 1]
elif token == ":":
if obj.type != "tree":
obj = obj.tree
@@ -269,29 +271,31 @@ def rev_parse(repo, rev):
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
#} END utilities
+
class PureReferencesMixin(ReferencesMixin):
+
"""Pure-Python refparse implementation"""
-
+
re_hexsha_only = re.compile('^[0-9A-Fa-f]{40}$')
re_hexsha_shortened = re.compile('^[0-9A-Fa-f]{4,40}$')
-
+
#{ Configuration
# Types to use when instatiating references
TagReferenceCls = TagReference
@@ -300,64 +304,62 @@ class PureReferencesMixin(ReferencesMixin):
HEADCls = HEAD
CommitCls = Commit
#} END configuration
-
+
def resolve(self, name):
return self.resolve_object(name).binsha
-
+
def resolve_object(self, name):
return rev_parse(self, name)
-
+
@property
def references(self):
return self.ReferenceCls.list_items(self)
-
+
@property
def heads(self):
return self.HeadCls.list_items(self)
-
+
@property
def tags(self):
return self.TagReferenceCls.list_items(self)
-
+
def tag(self, name):
return self.TagReferenceCls(self, self.TagReferenceCls.to_full_path(name))
-
+
def commit(self, rev=None):
if rev is None:
return self.head.commit
else:
- return self.resolve_object(str(rev)+"^0")
- #END handle revision
-
+ return self.resolve_object(str(rev) + "^0")
+ # END handle revision
+
def iter_trees(self, *args, **kwargs):
- return ( c.tree for c in self.iter_commits(*args, **kwargs) )
+ return (c.tree for c in self.iter_commits(*args, **kwargs))
def tree(self, rev=None):
if rev is None:
return self.head.commit.tree
else:
- return self.resolve_object(str(rev)+"^{tree}")
+ return self.resolve_object(str(rev) + "^{tree}")
def iter_commits(self, rev=None, paths='', **kwargs):
if rev is None:
rev = self.head.commit
-
+
return self.CommitCls.iter_items(self, rev, paths, **kwargs)
-
@property
def head(self):
- return self.HEADCls(self,'HEAD')
-
- def create_head(self, path, commit='HEAD', force=False, logmsg=None ):
+ return self.HEADCls(self, 'HEAD')
+
+ def create_head(self, path, commit='HEAD', force=False, logmsg=None):
return self.HeadCls.create(self, path, commit, force, logmsg)
-
+
def delete_head(self, *heads, **kwargs):
return self.HeadCls.delete(self, *heads, **kwargs)
-
+
def create_tag(self, path, ref='HEAD', message=None, force=False, **kwargs):
return self.TagReferenceCls.create(self, path, ref, message, force, **kwargs)
-
+
def delete_tag(self, *tags):
return self.TagReferenceCls.delete(self, *tags)
-