Skip to content

Commit 264ba6f

Browse files
committed
Fixed remaining issues, all tests work as expected
1 parent ec0657c commit 264ba6f

File tree

7 files changed

+56
-32
lines changed

7 files changed

+56
-32
lines changed

objects/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# imported by the submodule.base
88
import submodule.util
99
submodule.util.IndexObject = IndexObject
10+
submodule.util.Object = Object
1011
from submodule.base import *
1112
from submodule.root import *
1213

objects/base.py

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def new_from_sha(cls, repo, sha1):
5757
:return: new object instance of a type appropriate to represent the given
5858
binary sha1
5959
:param sha1: 20 byte binary sha1"""
60+
if sha1 == cls.NULL_BIN_SHA:
61+
# the NULL binsha is always the root commit
62+
return get_object_type_by_name('commit')(repo, sha1)
63+
#END handle special case
6064
oinfo = repo.odb.info(sha1)
6165
inst = get_object_type_by_name(oinfo.type)(repo, oinfo.binsha)
6266
inst.size = oinfo.size

objects/submodule/base.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
join_path_native,
1515
to_native_path_linux
1616
)
17+
1718
from git.config import SectionConstraint
1819
from git.exc import (
1920
InvalidGitRepositoryError,
@@ -339,14 +340,7 @@ def update(self, recursive=False, init=True, to_latest_revision=False):
339340

340341
# have a valid branch, but no checkout - make sure we can figure
341342
# that out by marking the commit with a null_sha
342-
# have to write it directly as .commit = NULLSHA tries to resolve the sha
343-
# This will bring the branch into existance
344-
refpath = join_path_native(mrepo.git_dir, local_branch.path)
345-
refdir = os.path.dirname(refpath)
346-
if not os.path.isdir(refdir):
347-
os.makedirs(refdir)
348-
#END handle directory
349-
open(refpath, 'w').write(self.NULL_HEX_SHA)
343+
local_branch.set_object(util.Object(mrepo, self.NULL_BIN_SHA))
350344
# END initial checkout + branch creation
351345

352346
# make sure HEAD is not detached

refs/symbolic.py

+32-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
assure_directory_exists
88
)
99

10+
from gitdb.exc import BadObject
1011
from gitdb.util import (
1112
join,
1213
dirname,
@@ -114,13 +115,13 @@ def dereference_recursive(cls, repo, ref_path):
114115
# END recursive dereferencing
115116

116117
@classmethod
117-
def _get_ref_info(cls, repo, path):
118+
def _get_ref_info(cls, repo, ref_path):
118119
"""Return: (sha, target_ref_path) if available, the sha the file at
119120
rela_path points to, or None. target_ref_path is the reference we
120121
point to, or None"""
121122
tokens = None
122123
try:
123-
fp = open(join(repo.git_dir, path), 'r')
124+
fp = open(join(repo.git_dir, ref_path), 'r')
124125
value = fp.read().rstrip()
125126
fp.close()
126127
tokens = value.split(" ")
@@ -129,14 +130,13 @@ def _get_ref_info(cls, repo, path):
129130
# NOTE: We are not a symbolic ref if we are in a packed file, as these
130131
# are excluded explictly
131132
for sha, path in cls._iter_packed_refs(repo):
132-
if path != path: continue
133+
if path != ref_path: continue
133134
tokens = (sha, path)
134135
break
135136
# END for each packed ref
136137
# END handle packed refs
137-
138138
if tokens is None:
139-
raise ValueError("Reference at %r does not exist" % path)
139+
raise ValueError("Reference at %r does not exist" % ref_path)
140140

141141
# is it a reference ?
142142
if tokens[0] == 'ref:':
@@ -146,7 +146,7 @@ def _get_ref_info(cls, repo, path):
146146
if repo.re_hexsha_only.match(tokens[0]):
147147
return (tokens[0], None)
148148

149-
raise ValueError("Failed to parse reference information from %r" % path)
149+
raise ValueError("Failed to parse reference information from %r" % ref_path)
150150

151151
def _get_object(self):
152152
"""
@@ -163,18 +163,38 @@ def _get_commit(self):
163163
Commit object we point to, works for detached and non-detached
164164
SymbolicReferences. The symbolic reference will be dereferenced recursively."""
165165
obj = self._get_object()
166+
if obj.type == 'tag':
167+
obj = obj.object
168+
#END dereference tag
169+
166170
if obj.type != Commit.type:
167171
raise TypeError("Symbolic Reference pointed to object %r, commit was required" % obj)
168172
#END handle type
169173
return obj
170174

171175
def set_commit(self, commit, msg = None):
172176
"""As set_object, but restricts the type of object to be a Commit
173-
:note: To save cycles, we do not yet check whether the given Object
174-
is actually referring to a commit - for now it may be any of our
175-
Object or Reference types, as well as a refspec"""
176-
# may have to check the type ... this is costly as we would have to use
177-
# revparse
177+
:raise ValueError: If commit is not a Commit object or doesn't point to
178+
a commit"""
179+
# check the type - assume the best if it is a base-string
180+
invalid_type = False
181+
if isinstance(commit, Object):
182+
invalid_type = commit.type != Commit.type
183+
elif isinstance(commit, SymbolicReference):
184+
invalid_type = commit.object.type != Commit.type
185+
else:
186+
try:
187+
invalid_type = self.repo.rev_parse(commit).type != Commit.type
188+
except BadObject:
189+
raise ValueError("Invalid object: %s" % commit)
190+
#END handle exception
191+
# END verify type
192+
193+
if invalid_type:
194+
raise ValueError("Need commit, got %r" % commit)
195+
#END handle raise
196+
197+
# we leave strings to the rev-parse method below
178198
self.set_object(commit, msg)
179199

180200

@@ -243,7 +263,7 @@ def set_reference(self, ref, msg = None):
243263
try:
244264
obj = self.repo.rev_parse(ref+"^{}") # optionally deref tags
245265
write_value = obj.hexsha
246-
except Exception:
266+
except BadObject:
247267
raise ValueError("Could not extract object from %s" % ref)
248268
# END end try string
249269
else:

test/test_reflog.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def test_base(self):
6060
# test serialize and deserialize - results must match exactly
6161
binsha = chr(255)*20
6262
msg = "my reflog message"
63-
cr = repo.config_reader()
63+
cr = self.rorepo.config_reader()
6464
for rlp in (rlp_head, rlp_master):
6565
reflog = RefLog.from_file(rlp)
6666
tfile = os.path.join(tdir, os.path.basename(rlp))

test/test_refs.py

+15-11
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
class TestRefs(TestBase):
1717

18-
def _test_from_path(self):
18+
def test_from_path(self):
1919
# should be able to create any reference directly
2020
for ref_type in ( Reference, Head, TagReference, RemoteReference ):
2121
for name in ('rela_name', 'path/rela_name'):
@@ -25,7 +25,7 @@ def _test_from_path(self):
2525
# END for each name
2626
# END for each type
2727

28-
def _test_tag_base(self):
28+
def test_tag_base(self):
2929
tag_object_refs = list()
3030
for tag in self.rorepo.tags:
3131
assert "refs/tags" in tag.path
@@ -50,7 +50,7 @@ def _test_tag_base(self):
5050
assert tag_object_refs
5151
assert isinstance(self.rorepo.tags['0.1.5'], TagReference)
5252

53-
def _test_tags(self):
53+
def test_tags(self):
5454
# tag refs can point to tag objects or to commits
5555
s = set()
5656
ref_count = 0
@@ -67,7 +67,7 @@ def _test_tags(self):
6767
assert len(s|s) == ref_count
6868

6969
@with_rw_repo('HEAD', bare=False)
70-
def _test_heads(self, rwrepo):
70+
def test_heads(self, rwrepo):
7171
for head in rwrepo.heads:
7272
assert head.name
7373
assert head.path
@@ -129,7 +129,7 @@ def _test_heads(self, rwrepo):
129129
# TODO: Need changing a ref changes HEAD reflog as well if it pointed to it
130130

131131

132-
def _test_refs(self):
132+
def test_refs(self):
133133
types_found = set()
134134
for ref in self.rorepo.refs:
135135
types_found.add(type(ref))
@@ -142,7 +142,7 @@ def test_is_valid(self):
142142
assert SymbolicReference(self.rorepo, 'hellothere').is_valid() == False
143143

144144
@with_rw_repo('0.1.6')
145-
def _test_head_reset(self, rw_repo):
145+
def test_head_reset(self, rw_repo):
146146
cur_head = rw_repo.head
147147
old_head_commit = cur_head.commit
148148
new_head_commit = cur_head.ref.commit.parents[0]
@@ -292,7 +292,11 @@ def _test_head_reset(self, rw_repo):
292292
head_tree = head.commit.tree
293293
self.failUnlessRaises(ValueError, setattr, head, 'commit', head_tree)
294294
assert head.commit == old_commit # and the ref did not change
295-
self.failUnlessRaises(GitCommandError, setattr, head, 'object', head_tree)
295+
# we allow heds to point to any object
296+
head.object = head_tree
297+
assert head.object == head_tree
298+
# cannot query tree as commit
299+
self.failUnlessRaises(TypeError, getattr, head, 'commit')
296300

297301
# set the commit directly using the head. This would never detach the head
298302
assert not cur_head.is_detached
@@ -488,20 +492,20 @@ def _test_head_reset(self, rw_repo):
488492

489493
Reference.delete(ref.repo, ref.path)
490494
assert not ref.is_valid()
491-
self.failUnlessRaises(GitCommandError, setattr, ref, 'object', "nonsense")
495+
self.failUnlessRaises(ValueError, setattr, ref, 'object', "nonsense")
492496
assert not ref.is_valid()
493497

494498
# END for each path
495499

496-
def _test_dereference_recursive(self):
500+
def test_dereference_recursive(self):
497501
# for now, just test the HEAD
498502
assert SymbolicReference.dereference_recursive(self.rorepo, 'HEAD')
499503

500-
def _test_reflog(self):
504+
def test_reflog(self):
501505
assert isinstance(self.rorepo.heads.master.log(), RefLog)
502506

503507

504-
def _test_todo(self):
508+
def test_todo(self):
505509
# delete deletes the reflog
506510
# create creates a new entry
507511
# set_reference and set_commit and set_object use the reflog if message is given

test/test_submodule.py

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ def _do_base_tests(self, rwrepo):
107107

108108
# currently there is only one submodule
109109
assert len(list(rwrepo.iter_submodules())) == 1
110+
assert sm.binsha != "\0"*20
110111

111112
# TEST ADD
112113
###########

0 commit comments

Comments
 (0)