diff options
| -rw-r--r-- | TODO | 10 | ||||
| -rw-r--r-- | lib/git/refs.py | 48 | ||||
| -rw-r--r-- | test/git/test_refs.py | 18 | 
3 files changed, 60 insertions, 16 deletions
| @@ -67,15 +67,7 @@ Refs  -----  * When adjusting the reference of a symbolic reference, the ref log might need     adjustments as well. This is not critical, but would make things totally 'right' -* Reference Objects should be able to set the commit they are pointing to, making  -  the commit property read-write. Tags are a special case of this and would need  -  to be handled as well ! -* Ability to create new heads and tags in the Repository ( but using the respective -  Reference Type ), i.e. Head.create(repo, name, commit = 'HEAD') or  -  TagReference.create(repo, name -* Ability to rename references and tagsre -* Ability to remove references and tags -* Ability to checkout a reference -  +  - same with adjusting references directly  * Check whether we are the active reference HEAD.commit == self.commit  Remote diff --git a/lib/git/refs.py b/lib/git/refs.py index 0efee52e..47c37af6 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -65,8 +65,7 @@ class Reference(LazyMixin, Iterable):  		return '/'.join(tokens[2:]) -	@property -	def object(self): +	def _get_object(self):  		"""  		Returns  			The object our ref currently refers to. Refs can be cached, they will  @@ -76,17 +75,54 @@ class Reference(LazyMixin, Iterable):  		# Our path will be resolved to the hexsha which will be used accordingly  		return Object.new(self.repo, self.path) -	@property -	def commit(self): +	def _set_object(self, ref, type=None):  		""" +		Set our reference to point to the given ref. It will be converted +		to a specific hexsha. +		 +		``type`` +			If not None, string type of that the object must have, other we raise +			a type error. Only used internally +		  		Returns -			Commit object the head points to +			Object we have set. This is used internally only to reduce the amount  +			of calls to the git command +		""" +		obj = Object.new(self.repo, ref) +		if type is not None and obj.type != type: +			raise TypeError("Reference %r cannot point to object of type %r" % (self,obj.type)) +			 +		full_ref_path = os.path.join(self.repo.path, self.path) +		fp = open(full_ref_path, "w") +		try: +			fp.write(str(obj)) +		finally: +			fp.close() +		return obj +		 +	object = property(_get_object, _set_object, doc="Return the object our ref currently refers to") +		 +	def _set_commit(self, commit): +		""" +		Set ourselves to point to the given commit.  +		 +		Raise +			ValueError if commit does not actually point to a commit +		""" +		self._set_object(commit, type="commit") +		 +	def _get_commit(self): +		""" +		Returns +			Commit object the reference points to  		"""  		commit = self.object  		if commit.type != "commit":  			raise TypeError("Object of reference %s did not point to a commit" % self)  		return commit +	commit = property(_get_commit, _set_commit, doc="Return Commit object the reference points to") +	  	@classmethod  	def iter_items(cls, repo, common_path = None, **kwargs):  		""" @@ -244,7 +280,7 @@ class SymbolicReference(object):  		try:  			tokens = fp.readline().rstrip().split(' ')  			if tokens[0] != 'ref:': -				raise TypeError("%s is a detached symbolic reference as it points to %r" % tokens[0]) +				raise TypeError("%s is a detached symbolic reference as it points to %r" % (self, tokens[0]))  			return Reference.from_path(self.repo, tokens[1])  		finally:  			fp.close() diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 88e8a21a..696b95c7 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -181,4 +181,20 @@ class TestRefs(TestBase):  			self.failUnlessRaises(AssertionError, getattr, remote, 'refs')  		# END for each remote -		self.fail("set commit using ref.commit = that") +		# change where the active head points to +		if cur_head.is_detached: +			cur_head.reference = rw_repo.heads[0] +		 +		head = cur_head.reference +		old_commit = head.commit +		head.commit = old_commit.parents[0] +		assert head.commit == old_commit.parents[0] +		assert head.commit == cur_head.commit +		head.commit = old_commit +		 +		# setting a non-commit as commit fails, but succeeds as object +		head_tree = head.commit.tree +		self.failUnlessRaises(TypeError, setattr, head, 'commit', head_tree) +		assert head.commit == old_commit		# and the ref did not change +		head.object = head_tree +		assert head.object == head_tree | 
