summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-11-24 17:12:36 +0100
committerSebastian Thiel <byronimo@gmail.com>2010-11-24 17:12:36 +0100
commit264ba6f54f928da31a037966198a0849325b3732 (patch)
tree3cc84ae352307fd5fded67f6a0c1e4fd376ed843
parentec0657cf5de9aeb5629cc4f4f38b36f48490493e (diff)
downloadgitpython-264ba6f54f928da31a037966198a0849325b3732.tar.gz
Fixed remaining issues, all tests work as expected
-rw-r--r--objects/__init__.py1
-rw-r--r--objects/base.py4
-rw-r--r--objects/submodule/base.py10
-rw-r--r--refs/symbolic.py44
-rw-r--r--test/test_reflog.py2
-rw-r--r--test/test_refs.py26
-rw-r--r--test/test_submodule.py1
7 files changed, 56 insertions, 32 deletions
diff --git a/objects/__init__.py b/objects/__init__.py
index 65659cd1..77f69d29 100644
--- a/objects/__init__.py
+++ b/objects/__init__.py
@@ -7,6 +7,7 @@ from base import *
# imported by the submodule.base
import submodule.util
submodule.util.IndexObject = IndexObject
+submodule.util.Object = Object
from submodule.base import *
from submodule.root import *
diff --git a/objects/base.py b/objects/base.py
index b8cec47f..5f2f7809 100644
--- a/objects/base.py
+++ b/objects/base.py
@@ -57,6 +57,10 @@ class Object(LazyMixin):
:return: new object instance of a type appropriate to represent the given
binary sha1
:param sha1: 20 byte binary sha1"""
+ if sha1 == cls.NULL_BIN_SHA:
+ # the NULL binsha is always the root commit
+ return get_object_type_by_name('commit')(repo, sha1)
+ #END handle special case
oinfo = repo.odb.info(sha1)
inst = get_object_type_by_name(oinfo.type)(repo, oinfo.binsha)
inst.size = oinfo.size
diff --git a/objects/submodule/base.py b/objects/submodule/base.py
index 4f4223b6..5d32d600 100644
--- a/objects/submodule/base.py
+++ b/objects/submodule/base.py
@@ -14,6 +14,7 @@ from git.util import (
join_path_native,
to_native_path_linux
)
+
from git.config import SectionConstraint
from git.exc import (
InvalidGitRepositoryError,
@@ -339,14 +340,7 @@ class Submodule(util.IndexObject, Iterable, Traversable):
# have a valid branch, but no checkout - make sure we can figure
# that out by marking the commit with a null_sha
- # have to write it directly as .commit = NULLSHA tries to resolve the sha
- # This will bring the branch into existance
- refpath = join_path_native(mrepo.git_dir, local_branch.path)
- refdir = os.path.dirname(refpath)
- if not os.path.isdir(refdir):
- os.makedirs(refdir)
- #END handle directory
- open(refpath, 'w').write(self.NULL_HEX_SHA)
+ local_branch.set_object(util.Object(mrepo, self.NULL_BIN_SHA))
# END initial checkout + branch creation
# make sure HEAD is not detached
diff --git a/refs/symbolic.py b/refs/symbolic.py
index 2ecdee4a..83dbafd2 100644
--- a/refs/symbolic.py
+++ b/refs/symbolic.py
@@ -7,6 +7,7 @@ from git.util import (
assure_directory_exists
)
+from gitdb.exc import BadObject
from gitdb.util import (
join,
dirname,
@@ -114,13 +115,13 @@ class SymbolicReference(object):
# END recursive dereferencing
@classmethod
- def _get_ref_info(cls, repo, path):
+ def _get_ref_info(cls, repo, ref_path):
"""Return: (sha, target_ref_path) if available, the sha the file at
rela_path points to, or None. target_ref_path is the reference we
point to, or None"""
tokens = None
try:
- fp = open(join(repo.git_dir, path), 'r')
+ fp = open(join(repo.git_dir, ref_path), 'r')
value = fp.read().rstrip()
fp.close()
tokens = value.split(" ")
@@ -129,14 +130,13 @@ class SymbolicReference(object):
# NOTE: We are not a symbolic ref if we are in a packed file, as these
# are excluded explictly
for sha, path in cls._iter_packed_refs(repo):
- if path != path: continue
+ if path != ref_path: continue
tokens = (sha, path)
break
# END for each packed ref
# END handle packed refs
-
if tokens is None:
- raise ValueError("Reference at %r does not exist" % path)
+ raise ValueError("Reference at %r does not exist" % ref_path)
# is it a reference ?
if tokens[0] == 'ref:':
@@ -146,7 +146,7 @@ class SymbolicReference(object):
if repo.re_hexsha_only.match(tokens[0]):
return (tokens[0], None)
- raise ValueError("Failed to parse reference information from %r" % path)
+ raise ValueError("Failed to parse reference information from %r" % ref_path)
def _get_object(self):
"""
@@ -163,6 +163,10 @@ class SymbolicReference(object):
Commit object we point to, works for detached and non-detached
SymbolicReferences. The symbolic reference will be dereferenced recursively."""
obj = self._get_object()
+ if obj.type == 'tag':
+ obj = obj.object
+ #END dereference tag
+
if obj.type != Commit.type:
raise TypeError("Symbolic Reference pointed to object %r, commit was required" % obj)
#END handle type
@@ -170,11 +174,27 @@ class SymbolicReference(object):
def set_commit(self, commit, msg = None):
"""As set_object, but restricts the type of object to be a Commit
- :note: To save cycles, we do not yet check whether the given Object
- is actually referring to a commit - for now it may be any of our
- Object or Reference types, as well as a refspec"""
- # may have to check the type ... this is costly as we would have to use
- # revparse
+ :raise ValueError: If commit is not a Commit object or doesn't point to
+ a commit"""
+ # check the type - assume the best if it is a base-string
+ invalid_type = False
+ if isinstance(commit, Object):
+ invalid_type = commit.type != Commit.type
+ elif isinstance(commit, SymbolicReference):
+ invalid_type = commit.object.type != Commit.type
+ else:
+ try:
+ invalid_type = self.repo.rev_parse(commit).type != Commit.type
+ except BadObject:
+ raise ValueError("Invalid object: %s" % commit)
+ #END handle exception
+ # END verify type
+
+ if invalid_type:
+ raise ValueError("Need commit, got %r" % commit)
+ #END handle raise
+
+ # we leave strings to the rev-parse method below
self.set_object(commit, msg)
@@ -243,7 +263,7 @@ class SymbolicReference(object):
try:
obj = self.repo.rev_parse(ref+"^{}") # optionally deref tags
write_value = obj.hexsha
- except Exception:
+ except BadObject:
raise ValueError("Could not extract object from %s" % ref)
# END end try string
else:
diff --git a/test/test_reflog.py b/test/test_reflog.py
index 0c8e538b..520be590 100644
--- a/test/test_reflog.py
+++ b/test/test_reflog.py
@@ -60,7 +60,7 @@ class TestRefLog(TestBase):
# test serialize and deserialize - results must match exactly
binsha = chr(255)*20
msg = "my reflog message"
- cr = repo.config_reader()
+ cr = self.rorepo.config_reader()
for rlp in (rlp_head, rlp_master):
reflog = RefLog.from_file(rlp)
tfile = os.path.join(tdir, os.path.basename(rlp))
diff --git a/test/test_refs.py b/test/test_refs.py
index f0d648f1..fefce6be 100644
--- a/test/test_refs.py
+++ b/test/test_refs.py
@@ -15,7 +15,7 @@ import os
class TestRefs(TestBase):
- def _test_from_path(self):
+ def test_from_path(self):
# should be able to create any reference directly
for ref_type in ( Reference, Head, TagReference, RemoteReference ):
for name in ('rela_name', 'path/rela_name'):
@@ -25,7 +25,7 @@ class TestRefs(TestBase):
# END for each name
# END for each type
- def _test_tag_base(self):
+ def test_tag_base(self):
tag_object_refs = list()
for tag in self.rorepo.tags:
assert "refs/tags" in tag.path
@@ -50,7 +50,7 @@ class TestRefs(TestBase):
assert tag_object_refs
assert isinstance(self.rorepo.tags['0.1.5'], TagReference)
- def _test_tags(self):
+ def test_tags(self):
# tag refs can point to tag objects or to commits
s = set()
ref_count = 0
@@ -67,7 +67,7 @@ class TestRefs(TestBase):
assert len(s|s) == ref_count
@with_rw_repo('HEAD', bare=False)
- def _test_heads(self, rwrepo):
+ def test_heads(self, rwrepo):
for head in rwrepo.heads:
assert head.name
assert head.path
@@ -129,7 +129,7 @@ class TestRefs(TestBase):
# TODO: Need changing a ref changes HEAD reflog as well if it pointed to it
- def _test_refs(self):
+ def test_refs(self):
types_found = set()
for ref in self.rorepo.refs:
types_found.add(type(ref))
@@ -142,7 +142,7 @@ class TestRefs(TestBase):
assert SymbolicReference(self.rorepo, 'hellothere').is_valid() == False
@with_rw_repo('0.1.6')
- def _test_head_reset(self, rw_repo):
+ def test_head_reset(self, rw_repo):
cur_head = rw_repo.head
old_head_commit = cur_head.commit
new_head_commit = cur_head.ref.commit.parents[0]
@@ -292,7 +292,11 @@ class TestRefs(TestBase):
head_tree = head.commit.tree
self.failUnlessRaises(ValueError, setattr, head, 'commit', head_tree)
assert head.commit == old_commit # and the ref did not change
- self.failUnlessRaises(GitCommandError, setattr, head, 'object', head_tree)
+ # we allow heds to point to any object
+ head.object = head_tree
+ assert head.object == head_tree
+ # cannot query tree as commit
+ self.failUnlessRaises(TypeError, getattr, head, 'commit')
# set the commit directly using the head. This would never detach the head
assert not cur_head.is_detached
@@ -488,20 +492,20 @@ class TestRefs(TestBase):
Reference.delete(ref.repo, ref.path)
assert not ref.is_valid()
- self.failUnlessRaises(GitCommandError, setattr, ref, 'object', "nonsense")
+ self.failUnlessRaises(ValueError, setattr, ref, 'object', "nonsense")
assert not ref.is_valid()
# END for each path
- def _test_dereference_recursive(self):
+ def test_dereference_recursive(self):
# for now, just test the HEAD
assert SymbolicReference.dereference_recursive(self.rorepo, 'HEAD')
- def _test_reflog(self):
+ def test_reflog(self):
assert isinstance(self.rorepo.heads.master.log(), RefLog)
- def _test_todo(self):
+ def test_todo(self):
# delete deletes the reflog
# create creates a new entry
# set_reference and set_commit and set_object use the reflog if message is given
diff --git a/test/test_submodule.py b/test/test_submodule.py
index c1fa2061..f69c27ea 100644
--- a/test/test_submodule.py
+++ b/test/test_submodule.py
@@ -107,6 +107,7 @@ class TestSubmodule(TestBase):
# currently there is only one submodule
assert len(list(rwrepo.iter_submodules())) == 1
+ assert sm.binsha != "\0"*20
# TEST ADD
###########