From 6e5aae2fc8c3832bdae1cd5e0a269405fb059231 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 23 Nov 2010 12:35:34 +0100 Subject: Initial interface including some of the implementation of the RefLog. TestCase scetched out for now tests: Added tests to verify that objects don't have a dict. Previously, due to a missing __slots__ member in Serializable, most objects would indeed have a dict, although the opposite was intended --- test/test_refs.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index 700e5fac..ebf1a00d 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -33,6 +33,8 @@ class TestRefs(TestBase): if tag.tag is not None: tag_object_refs.append( tag ) tagobj = tag.tag + # have no dict + self.failUnlessRaises(AttributeError, setattr, tagobj, 'someattr', 1) assert isinstance( tagobj, TagObject ) assert tagobj.tag == tag.name assert isinstance( tagobj.tagger, Actor ) -- cgit v1.2.3 From 8ad01ee239f9111133e52af29b78daed34c52e49 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 23 Nov 2010 15:58:32 +0100 Subject: SymbolicReference: log method added, including test --- test/test_refs.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index ebf1a00d..1f3dfb9f 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -488,3 +488,6 @@ class TestRefs(TestBase): def test_dereference_recursive(self): # for now, just test the HEAD assert SymbolicReference.dereference_recursive(self.rorepo, 'HEAD') + + def test_reflog(self): + assert isinstance(self.rorepo.heads.master.log(), RefLog) -- cgit v1.2.3 From a21a9f6f13861ddc65671b278e93cf0984adaa30 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 23 Nov 2010 21:14:59 +0100 Subject: Actor: Moved it from git.objects.util to git.util, adjusted all imports accordingly. Added methods to Actor to retrieve the global committer and author information Reflog: implemented and tested append_entry method --- test/test_refs.py | 1 + 1 file changed, 1 insertion(+) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index 1f3dfb9f..c7764d92 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -8,6 +8,7 @@ from mock import * from git.test.lib import * from git import * import git.refs as refs +from git.util import Actor from git.objects.tag import TagObject from itertools import chain import os -- cgit v1.2.3 From 61f3db7bd07ac2f3c2ff54615c13bf9219289932 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 23 Nov 2010 22:47:34 +0100 Subject: Removed ORIG_HEAD handling which was downright wrong. ORIG_HEAD gets only set during merge and rebase, and probably everything that changes the ref more drastically. Probably I have to reread that. What needs to be adjusted though is the reflog --- test/test_refs.py | 61 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index c7764d92..0c0caaf2 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -95,35 +95,38 @@ class TestRefs(TestBase): assert head.tracking_branch() is None # END for each head - # verify ORIG_HEAD gets set for detached heads - head = rwrepo.head - orig_head = head.orig_head() - cur_head = head.ref - cur_commit = cur_head.commit - pcommit = cur_head.commit.parents[0].parents[0] - head.ref = pcommit # detach head - assert orig_head.commit == cur_commit - - # even if we set it through its reference - chaning the ref - # will adjust the orig_head, which still points to cur_commit - head.ref = cur_head - assert orig_head.commit == pcommit - assert head.commit == cur_commit == cur_head.commit - - cur_head.commit = pcommit - assert head.commit == pcommit - assert orig_head.commit == cur_commit - - # with automatic dereferencing - head.commit = cur_commit - assert orig_head.commit == pcommit - - # changing branches which are not checked out doesn't affect the ORIG_HEAD - other_head = Head.create(rwrepo, 'mynewhead', pcommit) - assert other_head.commit == pcommit - assert orig_head.commit == pcommit - other_head.commit = pcommit.parents[0] - assert orig_head.commit == pcommit + # verify REFLOG gets altered + if False: + head = rwrepo.head + orig_head = head.orig_head() + cur_head = head.ref + cur_commit = cur_head.commit + pcommit = cur_head.commit.parents[0].parents[0] + head.ref = pcommit # detach head + assert orig_head.commit == cur_commit + + # even if we set it through its reference - chaning the ref + # will adjust the orig_head, which still points to cur_commit + head.ref = cur_head + assert orig_head.commit == pcommit + assert head.commit == cur_commit == cur_head.commit + + cur_head.commit = pcommit + assert head.commit == pcommit + assert orig_head.commit == cur_commit + + # with automatic dereferencing + head.commit = cur_commit + assert orig_head.commit == pcommit + + # changing branches which are not checked out doesn't affect the ORIG_HEAD + other_head = Head.create(rwrepo, 'mynewhead', pcommit) + assert other_head.commit == pcommit + assert orig_head.commit == pcommit + other_head.commit = pcommit.parents[0] + assert orig_head.commit == pcommit + + # TODO: Need changing a ref changes HEAD reflog as well if it pointed to it def test_refs(self): -- cgit v1.2.3 From a17c43d0662bab137903075f2cff34bcabc7e1d1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 24 Nov 2010 12:30:51 +0100 Subject: Made previously protected methods public to introduce a method with reflog support which cannot be exposed using the respective property. Ref-Creation is now fully implemented in python. For details, see doc/source/changes.rst --- test/test_refs.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index 0c0caaf2..3b7ad9e7 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -205,10 +205,14 @@ class TestRefs(TestBase): for count, new_name in enumerate(("my_new_head", "feature/feature1")): actual_commit = commit+"^"*count new_head = Head.create(rw_repo, new_name, actual_commit) + assert new_head.is_detached assert cur_head.commit == prev_head_commit assert isinstance(new_head, Head) - # already exists - self.failUnlessRaises(GitCommandError, Head.create, rw_repo, new_name) + # already exists, but has the same value, so its fine + Head.create(rw_repo, new_name, new_head.commit) + + # its not fine with a different value + self.failUnlessRaises(OSError, Head.create, rw_repo, new_name, new_head.commit.parents[0]) # force it new_head = Head.create(rw_repo, new_name, actual_commit, force=True) @@ -230,7 +234,7 @@ class TestRefs(TestBase): assert tmp_head not in heads and new_head not in heads # force on deletion testing would be missing here, code looks okay though ;) # END for each new head name - self.failUnlessRaises(TypeError, RemoteReference.create, rw_repo, "some_name") + self.failUnlessRaises(TypeError, RemoteReference.create, rw_repo, "some_name") # tag ref tag_name = "1.0.2" @@ -495,3 +499,10 @@ class TestRefs(TestBase): def test_reflog(self): assert isinstance(self.rorepo.heads.master.log(), RefLog) + + + 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 + self.fail() -- cgit v1.2.3 From ec0657cf5de9aeb5629cc4f4f38b36f48490493e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 24 Nov 2010 15:56:49 +0100 Subject: Unified object and commit handling which should make the reflog handling much easier. There is some bug in it though, it still needs fixing --- test/test_refs.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index 3b7ad9e7..f0d648f1 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] @@ -493,15 +493,15 @@ class TestRefs(TestBase): # 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 -- cgit v1.2.3 From 264ba6f54f928da31a037966198a0849325b3732 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 24 Nov 2010 17:12:36 +0100 Subject: Fixed remaining issues, all tests work as expected --- test/test_refs.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'test/test_refs.py') 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 -- cgit v1.2.3 From c946bf260d3f7ca54bffb796a82218dce0eb703f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 24 Nov 2010 17:51:22 +0100 Subject: Added tests for creation and adjustments of reference, verifying the log gets written --- test/test_refs.py | 73 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index fefce6be..3ad4dad2 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -96,38 +96,46 @@ class TestRefs(TestBase): # END for each head # verify REFLOG gets altered - if False: - head = rwrepo.head - orig_head = head.orig_head() - cur_head = head.ref - cur_commit = cur_head.commit - pcommit = cur_head.commit.parents[0].parents[0] - head.ref = pcommit # detach head - assert orig_head.commit == cur_commit - - # even if we set it through its reference - chaning the ref - # will adjust the orig_head, which still points to cur_commit - head.ref = cur_head - assert orig_head.commit == pcommit - assert head.commit == cur_commit == cur_head.commit - - cur_head.commit = pcommit - assert head.commit == pcommit - assert orig_head.commit == cur_commit - - # with automatic dereferencing - head.commit = cur_commit - assert orig_head.commit == pcommit - - # changing branches which are not checked out doesn't affect the ORIG_HEAD - other_head = Head.create(rwrepo, 'mynewhead', pcommit) - assert other_head.commit == pcommit - assert orig_head.commit == pcommit - other_head.commit = pcommit.parents[0] - assert orig_head.commit == pcommit - - # TODO: Need changing a ref changes HEAD reflog as well if it pointed to it - + head = rwrepo.head + cur_head = head.ref + cur_commit = cur_head.commit + pcommit = cur_head.commit.parents[0].parents[0] + hlog_len = len(head.log()) + blog_len = len(cur_head.log()) + head.set_reference(pcommit, 'detached head') + # one new log-entry + thlog = head.log() + assert len(thlog) == hlog_len + 1 + assert thlog[-1].oldhexsha == cur_commit.hexsha + assert thlog[-1].newhexsha == pcommit.hexsha + + # the ref didn't change though + assert len(cur_head.log()) == blog_len + + # head changes once again, cur_head doesn't change + head.set_reference(cur_head, 'reattach head') + assert len(head.log()) == hlog_len+2 + assert len(cur_head.log()) == blog_len + + # adjusting the head-ref also adjust the head, so both reflogs are + # altered + cur_head.set_commit(pcommit, 'changing commit') + assert len(cur_head.log()) == blog_len+1 + assert len(head.log()) == hlog_len+3 + + + # with automatic dereferencing + head.set_commit(cur_commit, 'change commit once again') + assert len(head.log()) == hlog_len+4 + assert len(cur_head.log()) == blog_len+2 + + # a new branch has just a single entry + other_head = Head.create(rwrepo, 'mynewhead', pcommit, msg='new head created') + log = other_head.log() + assert len(log) == 1 + assert log[0].oldhexsha == pcommit.NULL_HEX_SHA + assert log[0].newhexsha == pcommit.hexsha + def test_refs(self): types_found = set() @@ -509,4 +517,5 @@ class TestRefs(TestBase): # delete deletes the reflog # create creates a new entry # set_reference and set_commit and set_object use the reflog if message is given + # if there is no actual head-change, don't do anything self.fail() -- cgit v1.2.3 From 86523260c495d9a29aa5ab29d50d30a5d1981a0c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 24 Nov 2010 17:55:43 +0100 Subject: Renamed msg named parameter to logmsg, as it describes the purpose of the message much better Added test for deletion of reflog file when the corresponding ref is deleted --- test/test_refs.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'test/test_refs.py') diff --git a/test/test_refs.py b/test/test_refs.py index 3ad4dad2..52937de1 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -102,7 +102,7 @@ class TestRefs(TestBase): pcommit = cur_head.commit.parents[0].parents[0] hlog_len = len(head.log()) blog_len = len(cur_head.log()) - head.set_reference(pcommit, 'detached head') + assert head.set_reference(pcommit, 'detached head') is head # one new log-entry thlog = head.log() assert len(thlog) == hlog_len + 1 @@ -125,12 +125,12 @@ class TestRefs(TestBase): # with automatic dereferencing - head.set_commit(cur_commit, 'change commit once again') + assert head.set_commit(cur_commit, 'change commit once again') is head assert len(head.log()) == hlog_len+4 assert len(cur_head.log()) == blog_len+2 # a new branch has just a single entry - other_head = Head.create(rwrepo, 'mynewhead', pcommit, msg='new head created') + other_head = Head.create(rwrepo, 'mynewhead', pcommit, logmsg='new head created') log = other_head.log() assert len(log) == 1 assert log[0].oldhexsha == pcommit.NULL_HEX_SHA @@ -237,7 +237,11 @@ class TestRefs(TestBase): tmp_head.rename(new_head, force=True) assert tmp_head == new_head and tmp_head.object == new_head.object + logfile = RefLog.path(tmp_head) + assert os.path.isfile(logfile) Head.delete(rw_repo, tmp_head) + # deletion removes the log as well + assert not os.path.isfile(logfile) heads = rw_repo.heads assert tmp_head not in heads and new_head not in heads # force on deletion testing would be missing here, code looks okay though ;) @@ -512,10 +516,3 @@ class TestRefs(TestBase): def test_reflog(self): assert isinstance(self.rorepo.heads.master.log(), RefLog) - - 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 - # if there is no actual head-change, don't do anything - self.fail() -- cgit v1.2.3