diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2010-11-24 17:12:36 +0100 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2010-11-24 17:12:36 +0100 |
commit | 264ba6f54f928da31a037966198a0849325b3732 (patch) | |
tree | 3cc84ae352307fd5fded67f6a0c1e4fd376ed843 | |
parent | ec0657cf5de9aeb5629cc4f4f38b36f48490493e (diff) | |
download | gitpython-264ba6f54f928da31a037966198a0849325b3732.tar.gz |
Fixed remaining issues, all tests work as expected
-rw-r--r-- | objects/__init__.py | 1 | ||||
-rw-r--r-- | objects/base.py | 4 | ||||
-rw-r--r-- | objects/submodule/base.py | 10 | ||||
-rw-r--r-- | refs/symbolic.py | 44 | ||||
-rw-r--r-- | test/test_reflog.py | 2 | ||||
-rw-r--r-- | test/test_refs.py | 26 | ||||
-rw-r--r-- | test/test_submodule.py | 1 |
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 ########### |