From a1e2f63e64875a29e8c01a7ae17f5744680167a5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 11:37:14 +0100 Subject: submodule: Fleshed out interface, and a partial test which is not yet usable. It showed that the ConfigParser needs some work. If the root is set, it also needs to refer to the root_commit instead of to the root-tree, as it will have to decide whether it works on the working tree's version of the .gitmodules file or the one in the repository --- test/git/test_submodule.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 5f78b6e8..7922db77 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -6,7 +6,35 @@ from git import * class TestSubmodule(TestBase): - def test_base(self): - # TODO - pass + kCOTag = '0.1.6' + + def _do_base_tests(self, rwrepo): + """Perform all tests in the given repository, it may be bare or nonbare""" + + # uncached path/url - retrieves information from .gitmodules file + + # changing the root_tree yields new values when querying them (i.e. cache is cleared) + + + # size is invalid + self.failUnlessRaises(ValueError, getattr, sm, 'size') + + # fails if tree has no gitmodule file + + if rwrepo.bare: + # module fails + pass + else: + # get the module repository + pass + # END bare handling + + @with_rw_repo(kCOTag) + def test_base_rw(self, rwrepo): + self._do_base_tests(rwrepo) + + @with_bare_rw_repo + def test_base_bare(self, rwrepo): + self._do_base_tests(rwrepo) + -- cgit v1.2.3 From 4d36f8ff4d1274a8815e932285ad6dbd6b2888af Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 12:13:59 +0100 Subject: Improved GitConfigurationParser to better deal with streams and the corresponding locks. Submodule class now operates on parent_commits, the configuration is either streamed from the repository or written directly into a blob ( or file ) dependending on whether we have a working tree checkout or not which matches our parent_commit --- test/git/test_config.py | 4 +--- test/git/test_submodule.py | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/git/test_config.py b/test/git/test_config.py index 604a25f4..8c846b99 100644 --- a/test/git/test_config.py +++ b/test/git/test_config.py @@ -14,9 +14,7 @@ class TestBase(TestCase): def _to_memcache(self, file_path): fp = open(file_path, "r") - sio = StringIO.StringIO() - sio.write(fp.read()) - sio.seek(0) + sio = StringIO.StringIO(fp.read()) sio.name = file_path return sio diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 7922db77..7c8dffcb 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -19,7 +19,9 @@ class TestSubmodule(TestBase): # size is invalid self.failUnlessRaises(ValueError, getattr, sm, 'size') - # fails if tree has no gitmodule file + # set_parent_commit fails if tree has no gitmodule file + + if rwrepo.bare: # module fails @@ -28,6 +30,8 @@ class TestSubmodule(TestBase): # get the module repository pass # END bare handling + + # Writing of historical submodule configurations must not work @with_rw_repo(kCOTag) def test_base_rw(self, rwrepo): -- cgit v1.2.3 From 00ce31ad308ff4c7ef874d2fa64374f47980c85c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 16:53:12 +0100 Subject: Objects: Constructor now manually checks and sets the input arguments to the local cache - previously a procedural approach was used, which was less code, but slower too. Especially in case of CommitObjects unrolling the loop manually makes a difference. Submodule: Implemented query methods and did a bit of testing. More is to come, but the test works for now. As special addition, the submodule implementation uses the section name as submodule ID even though it seems to be just the path. This allows to make renames easier --- test/git/test_submodule.py | 73 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 7c8dffcb..f2bc43b5 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -2,14 +2,81 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php from test.testlib import * -from git import * +from git.exc import * +from git.objects.submodule import * class TestSubmodule(TestBase): - kCOTag = '0.1.6' + k_subm_changed = "394ed7006ee5dc8bddfd132b64001d5dfc0ffdd3" + k_no_subm_tag = "0.1.6" + def _do_base_tests(self, rwrepo): """Perform all tests in the given repository, it may be bare or nonbare""" + # manual instantiation + smm = Submodule(rwrepo, "\0"*20) + # name needs to be set in advance + self.failUnlessRaises(AttributeError, getattr, smm, 'name') + + # iterate - 1 submodule + sms = Submodule.list_items(rwrepo) + assert len(sms) == 1 + sm = sms[0] + + # at a different time, there is None + assert len(Submodule.list_items(rwrepo, self.k_no_subm_tag)) == 0 + + assert sm.path == 'lib/git/ext/gitdb' + assert sm.url == 'git://gitorious.org/git-python/gitdb.git' + assert sm.ref == 'master' # its unset in this case + assert sm.parent_commit == rwrepo.head.commit + + # some commits earlier we still have a submodule, but its at a different commit + smold = Submodule.iter_items(rwrepo, self.k_subm_changed).next() + assert smold.binsha != sm.binsha + assert smold != sm + + # force it to reread its information + del(smold._url) + smold.url == sm.url + + # test config_reader/writer methods + sm.config_reader() + sm.config_writer() + smold.config_reader() + # cannot get a writer on historical submodules + self.failUnlessRaises(ValueError, smold.config_writer) + + + # make the old into a new + prev_parent_commit = smold.parent_commit + smold.set_parent_commit('HEAD') + assert smold.parent_commit != prev_parent_commit + assert smold.binsha == sm.binsha + smold.set_parent_commit(prev_parent_commit) + assert smold.binsha != sm.binsha + + # raises if the sm didn't exist in new parent - it keeps its + # parent_commit unchanged + self.failUnlessRaises(ValueError, smold.set_parent_commit, self.k_no_subm_tag) + + # TEST TODO: if a path in the gitmodules file, but not in the index, it raises + + # module retrieval is not always possible + if rwrepo.bare: + self.failUnlessRaises(InvalidGitRepositoryError, sm.module) + else: + # its not checked out in our case + self.failUnlessRaises(InvalidGitRepositoryError, sm.module) + + # lets do it - its a recursive one too + + # delete the whole directory and re-initialize + # END handle bare mode + + + # Error if there is no submodule file here + self.failUnlessRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True) # uncached path/url - retrieves information from .gitmodules file @@ -33,7 +100,7 @@ class TestSubmodule(TestBase): # Writing of historical submodule configurations must not work - @with_rw_repo(kCOTag) + @with_rw_repo('HEAD') def test_base_rw(self, rwrepo): self._do_base_tests(rwrepo) -- cgit v1.2.3 From f97653aa06cf84bcf160be3786b6fce49ef52961 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 18:42:44 +0100 Subject: Repo: added submodule query and iteration methods similar to the ones provided for Remotes, including test --- test/git/test_repo.py | 10 ++++++++++ test/git/test_submodule.py | 33 ++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/git/test_repo.py b/test/git/test_repo.py index 65dce590..063b5dff 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -208,8 +208,10 @@ class TestRepo(TestBase): assert_equal('' % path, repr(self.rorepo)) def test_is_dirty_with_bare_repository(self): + orig_value = self.rorepo._bare self.rorepo._bare = True assert_false(self.rorepo.is_dirty()) + self.rorepo._bare = orig_value def test_is_dirty(self): self.rorepo._bare = False @@ -220,8 +222,10 @@ class TestRepo(TestBase): # END untracked files # END working tree # END index + orig_val = self.rorepo._bare self.rorepo._bare = True assert self.rorepo.is_dirty() == False + self.rorepo._bare = orig_val def test_head(self): assert self.rorepo.head.reference.object == self.rorepo.active_branch.object @@ -552,3 +556,9 @@ class TestRepo(TestBase): target_type = GitCmdObjectDB assert isinstance(self.rorepo.odb, target_type) + def test_submodules(self): + assert len(self.rorepo.submodules) == 1 # non-recursive + assert len(self.rorepo.list_submodules(recursive=True)) == 2 + + assert isinstance(self.rorepo.submodule("lib/git/ext/gitdb"), Submodule) + self.failUnlessRaises(ValueError, self.rorepo.submodule, "doesn't exist") diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index f2bc43b5..2ca0b269 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -7,6 +7,7 @@ from git.objects.submodule import * class TestSubmodule(TestBase): + k_subm_current = "00ce31ad308ff4c7ef874d2fa64374f47980c85c" k_subm_changed = "394ed7006ee5dc8bddfd132b64001d5dfc0ffdd3" k_no_subm_tag = "0.1.6" @@ -19,7 +20,7 @@ class TestSubmodule(TestBase): self.failUnlessRaises(AttributeError, getattr, smm, 'name') # iterate - 1 submodule - sms = Submodule.list_items(rwrepo) + sms = Submodule.list_items(rwrepo, self.k_subm_current) assert len(sms) == 1 sm = sms[0] @@ -27,6 +28,7 @@ class TestSubmodule(TestBase): assert len(Submodule.list_items(rwrepo, self.k_no_subm_tag)) == 0 assert sm.path == 'lib/git/ext/gitdb' + assert sm.path == sm.name # for now, this is True assert sm.url == 'git://gitorious.org/git-python/gitdb.git' assert sm.ref == 'master' # its unset in this case assert sm.parent_commit == rwrepo.head.commit @@ -47,10 +49,9 @@ class TestSubmodule(TestBase): # cannot get a writer on historical submodules self.failUnlessRaises(ValueError, smold.config_writer) - # make the old into a new prev_parent_commit = smold.parent_commit - smold.set_parent_commit('HEAD') + smold.set_parent_commit(self.k_subm_current) assert smold.parent_commit != prev_parent_commit assert smold.binsha == sm.binsha smold.set_parent_commit(prev_parent_commit) @@ -100,7 +101,7 @@ class TestSubmodule(TestBase): # Writing of historical submodule configurations must not work - @with_rw_repo('HEAD') + @with_rw_repo(k_subm_current) def test_base_rw(self, rwrepo): self._do_base_tests(rwrepo) @@ -108,4 +109,26 @@ class TestSubmodule(TestBase): def test_base_bare(self, rwrepo): self._do_base_tests(rwrepo) - + def test_root_module(self): + # Can query everything without problems + rm = RootModule(self.rorepo) + assert rm.module() is self.rorepo + + rm.binsha + rm.mode + rm.path + assert rm.name == rm.k_root_name + assert rm.parent_commit == self.rorepo.head.commit + rm.url + rm.ref + + assert len(rm.list_items(rm.module())) == 1 + rm.config_reader() + rm.config_writer() + + # deep traversal gitdb / async + assert len(list(rm.traverse())) == 2 + + # cannot set the parent commit as repo name doesn't exist + self.failUnlessRaises(ValueError, rm.set_parent_commit, 'HEAD') + -- cgit v1.2.3 From 624556eae1c292a1dc283d9dca1557e28abe8ee3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 19:03:53 +0100 Subject: Optimized test-decorators, by completely removing with_bare_rw_repo, which was mainly copy-paste from with_rw_repo, what a shame --- test/git/test_base.py | 2 +- test/git/test_commit.py | 2 +- test/git/test_remote.py | 2 +- test/git/test_repo.py | 2 +- test/git/test_submodule.py | 2 +- test/git/test_tree.py | 2 ++ test/testlib/helper.py | 53 +++++++++++++--------------------------------- 7 files changed, 22 insertions(+), 43 deletions(-) (limited to 'test') diff --git a/test/git/test_base.py b/test/git/test_base.py index db13feae..25d1e4e9 100644 --- a/test/git/test_base.py +++ b/test/git/test_base.py @@ -83,7 +83,7 @@ class TestBase(TestBase): # objects must be resolved to shas so they compare equal assert self.rorepo.head.reference.object == self.rorepo.active_branch.object - @with_bare_rw_repo + @with_rw_repo('HEAD', bare=True) def test_with_bare_rw_repo(self, bare_rw_repo): assert bare_rw_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isfile(os.path.join(bare_rw_repo.git_dir,'HEAD')) diff --git a/test/git/test_commit.py b/test/git/test_commit.py index 2692938f..c3ce5c92 100644 --- a/test/git/test_commit.py +++ b/test/git/test_commit.py @@ -237,7 +237,7 @@ class TestCommit(TestBase): name_rev = self.rorepo.head.commit.name_rev assert isinstance(name_rev, basestring) - @with_bare_rw_repo + @with_rw_repo('HEAD', bare=True) def test_serialization(self, rwrepo): # create all commits of our repo assert_commit_serialization(rwrepo, '0.1.6') diff --git a/test/git/test_remote.py b/test/git/test_remote.py index 1db4bc32..c52f907e 100644 --- a/test/git/test_remote.py +++ b/test/git/test_remote.py @@ -422,7 +422,7 @@ class TestRemote(TestBase): origin = rw_repo.remote('origin') assert origin == rw_repo.remotes.origin - @with_bare_rw_repo + @with_rw_repo('HEAD', bare=True) def test_creation_and_removal(self, bare_rw_repo): new_name = "test_new_one" arg_list = (new_name, "git@server:hello.git") diff --git a/test/git/test_repo.py b/test/git/test_repo.py index 063b5dff..3a59f05e 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -558,7 +558,7 @@ class TestRepo(TestBase): def test_submodules(self): assert len(self.rorepo.submodules) == 1 # non-recursive - assert len(self.rorepo.list_submodules(recursive=True)) == 2 + assert len(list(self.rorepo.iter_submodules())) == 2 assert isinstance(self.rorepo.submodule("lib/git/ext/gitdb"), Submodule) self.failUnlessRaises(ValueError, self.rorepo.submodule, "doesn't exist") diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 2ca0b269..ac179c22 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -105,7 +105,7 @@ class TestSubmodule(TestBase): def test_base_rw(self, rwrepo): self._do_base_tests(rwrepo) - @with_bare_rw_repo + @with_rw_repo(k_subm_current, bare=True) def test_base_bare(self, rwrepo): self._do_base_tests(rwrepo) diff --git a/test/git/test_tree.py b/test/git/test_tree.py index d08999bd..18688424 100644 --- a/test/git/test_tree.py +++ b/test/git/test_tree.py @@ -102,6 +102,8 @@ class TestTree(TestBase): assert isinstance(obj, (Blob, Tree)) all_items.append(obj) # END for each object + assert all_items == root.list_traverse() + # limit recursion level to 0 - should be same as default iteration assert all_items assert 'CHANGES' in root diff --git a/test/testlib/helper.py b/test/testlib/helper.py index b5b6fad7..c79ecaa1 100644 --- a/test/testlib/helper.py +++ b/test/testlib/helper.py @@ -14,6 +14,11 @@ import cStringIO GIT_REPO = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +__all__ = ( + 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', + 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO' + ) + #{ Routines def fixture_path(name): @@ -58,41 +63,7 @@ def _rmtree_onerror(osremove, fullpath, exec_info): os.chmod(fullpath, 0777) os.remove(fullpath) -def with_bare_rw_repo(func): - """ - Decorator providing a specially made read-write repository to the test case - decorated with it. The test case requires the following signature:: - def case(self, rw_repo) - - The rwrepo will be a bare clone or the types rorepo. Once the method finishes, - it will be removed completely. - - Use this if you want to make purely index based adjustments, change refs, create - heads, generally operations that do not need a working tree.""" - def bare_repo_creator(self): - repo_dir = tempfile.mktemp("bare_repo_%s" % func.__name__) - rw_repo = self.rorepo.clone(repo_dir, shared=True, bare=True) - prev_cwd = os.getcwd() - try: - try: - return func(self, rw_repo) - except: - # assure we keep the repo for debugging - print >> sys.stderr, "Keeping bare repo after failure: %s" % repo_dir - repo_dir = None - raise - # END handle exceptions - finally: - rw_repo.git.clear_cache() - if repo_dir is not None: - shutil.rmtree(repo_dir, onerror=_rmtree_onerror) - # END remove repo dir - # END cleanup - # END bare repo creator - bare_repo_creator.__name__ = func.__name__ - return bare_repo_creator - -def with_rw_repo(working_tree_ref): +def with_rw_repo(working_tree_ref, bare=False): """ Same as with_bare_repo, but clones the rorepo as non-bare repository, checking out the working tree at the given working_tree_ref. @@ -105,11 +76,17 @@ def with_rw_repo(working_tree_ref): assert isinstance(working_tree_ref, basestring), "Decorator requires ref name for working tree checkout" def argument_passer(func): def repo_creator(self): - repo_dir = tempfile.mktemp("non_bare_%s" % func.__name__) - rw_repo = self.rorepo.clone(repo_dir, shared=True, bare=False, n=True) + prefix = 'non_' + if bare: + prefix = '' + #END handle prefix + repo_dir = tempfile.mktemp("%sbare_%s" % (prefix, func.__name__)) + rw_repo = self.rorepo.clone(repo_dir, shared=True, bare=bare, n=True) rw_repo.head.commit = rw_repo.commit(working_tree_ref) - rw_repo.head.reference.checkout() + if not bare: + rw_repo.head.reference.checkout() + # END handle checkout prev_cwd = os.getcwd() os.chdir(rw_repo.working_dir) -- cgit v1.2.3 From ceee7d7e0d98db12067744ac3cd0ab3a49602457 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 15 Nov 2010 22:12:05 +0100 Subject: Added partial implementation of update, but realized that using refs in general may be contradicting if a tag is given there, as well as a commit sha of the submodule. Hence it should really be only a branch --- test/git/test_submodule.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index ac179c22..f015ad7f 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -51,7 +51,7 @@ class TestSubmodule(TestBase): # make the old into a new prev_parent_commit = smold.parent_commit - smold.set_parent_commit(self.k_subm_current) + assert smold.set_parent_commit(self.k_subm_current) is smold assert smold.parent_commit != prev_parent_commit assert smold.binsha == sm.binsha smold.set_parent_commit(prev_parent_commit) @@ -70,7 +70,9 @@ class TestSubmodule(TestBase): # its not checked out in our case self.failUnlessRaises(InvalidGitRepositoryError, sm.module) - # lets do it - its a recursive one too + # lets update it - its a recursive one too + # update fails if the path already exists non-empty + # self.failUnlessRaises( # delete the whole directory and re-initialize # END handle bare mode -- cgit v1.2.3 From d4fd7fca515ba9b088a7c811292f76f47d16cd7b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 00:18:13 +0100 Subject: Submodule now only supports branches to be given as hint that will svn-external like behaviour. Implemented first version of update, which works for now, but probably needs to see more features --- test/git/test_submodule.py | 47 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index f015ad7f..79413a9c 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -4,6 +4,10 @@ from test.testlib import * from git.exc import * from git.objects.submodule import * +from git.util import to_native_path_linux, join_path_native +import shutil +import git +import os class TestSubmodule(TestBase): @@ -30,8 +34,10 @@ class TestSubmodule(TestBase): assert sm.path == 'lib/git/ext/gitdb' assert sm.path == sm.name # for now, this is True assert sm.url == 'git://gitorious.org/git-python/gitdb.git' - assert sm.ref == 'master' # its unset in this case + assert sm.branch == 'master' # its unset in this case assert sm.parent_commit == rwrepo.head.commit + # size is invalid + self.failUnlessRaises(ValueError, getattr, sm, 'size') # some commits earlier we still have a submodule, but its at a different commit smold = Submodule.iter_items(rwrepo, self.k_subm_changed).next() @@ -44,10 +50,23 @@ class TestSubmodule(TestBase): # test config_reader/writer methods sm.config_reader() - sm.config_writer() + if rwrepo.bare: + self.failUnlessRaises(InvalidGitRepositoryError, sm.config_writer) + else: + writer = sm.config_writer() + # for faster checkout, set the url to the local path + new_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path)) + writer.set_value('url', new_path) + del(writer) + assert sm.config_reader().get_value('url') == new_path + assert sm.url == new_path + # END handle bare repo smold.config_reader() + # cannot get a writer on historical submodules - self.failUnlessRaises(ValueError, smold.config_writer) + if not rwrepo.bare: + self.failUnlessRaises(ValueError, smold.config_writer) + # END handle bare repo # make the old into a new prev_parent_commit = smold.parent_commit @@ -71,23 +90,37 @@ class TestSubmodule(TestBase): self.failUnlessRaises(InvalidGitRepositoryError, sm.module) # lets update it - its a recursive one too + newdir = os.path.join(sm.module_path(), 'dir') + os.makedirs(newdir) + # update fails if the path already exists non-empty - # self.failUnlessRaises( + self.failUnlessRaises(OSError, sm.update) + os.rmdir(newdir) + + assert sm.update() is sm + assert isinstance(sm.module(), git.Repo) + assert sm.module().working_tree_dir == sm.module_path() # delete the whole directory and re-initialize + shutil.rmtree(sm.module_path()) + sm.update(recursive=True) # END handle bare mode # Error if there is no submodule file here self.failUnlessRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True) + # TODO: Handle bare/unbare + # latest submodules write changes into the .gitmodules files + # uncached path/url - retrieves information from .gitmodules file + # index stays up-to-date with the working tree .gitmodules file + # changing the root_tree yields new values when querying them (i.e. cache is cleared) - # size is invalid - self.failUnlessRaises(ValueError, getattr, sm, 'size') + # set_parent_commit fails if tree has no gitmodule file @@ -122,7 +155,7 @@ class TestSubmodule(TestBase): assert rm.name == rm.k_root_name assert rm.parent_commit == self.rorepo.head.commit rm.url - rm.ref + rm.branch assert len(rm.list_items(rm.module())) == 1 rm.config_reader() -- cgit v1.2.3 From af5abca21b56fcf641ff916bd567680888c364aa Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 09:30:10 +0100 Subject: Added a few utility methods and improved the test. Refs need an improvement though to allow easy configuration of branch-specific settings --- test/git/test_submodule.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 79413a9c..5b1cad6c 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -88,6 +88,10 @@ class TestSubmodule(TestBase): else: # its not checked out in our case self.failUnlessRaises(InvalidGitRepositoryError, sm.module) + assert not sm.module_exists() + + # currently there is only one submodule + assert len(list(rwrepo.iter_submodules())) == 1 # lets update it - its a recursive one too newdir = os.path.join(sm.module_path(), 'dir') @@ -98,12 +102,29 @@ class TestSubmodule(TestBase): os.rmdir(newdir) assert sm.update() is sm + assert sm.module_exists() assert isinstance(sm.module(), git.Repo) assert sm.module().working_tree_dir == sm.module_path() # delete the whole directory and re-initialize shutil.rmtree(sm.module_path()) + sm.update(recursive=False) + assert len(list(rwrepo.iter_submodules())) == 2 + assert len(sm.children()) == 1 # its not checked out yet + csm = sm.children()[0] + assert not csm.module_exists() + + # adjust the path of the submodules module to point to the local destination + new_csm_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path, csm.path)) + csm.config_writer().set_value('url', new_csm_path) + assert csm.url == new_csm_path + + + # update recuesively again sm.update(recursive=True) + + # this flushed in a sub-submodule + assert len(list(rwrepo.iter_submodules())) == 2 # END handle bare mode -- cgit v1.2.3 From 9f73e8ba55f33394161b403bf7b8c2e0e05f47b0 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 11:05:31 +0100 Subject: remote: added methods to set and query the tracking branch status of normal heads, including test. Config: SectionConstraint was updated with additional callable methods, the complete ConfigParser interface should be covered now Remote: refs methods is much more efficient now as it will set the search path to the directory containing the remote refs - previously it used the remotes/ base directory and pruned the search result --- test/git/test_refs.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 5f13d0b7..4cfd952e 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -63,8 +63,9 @@ class TestRefs(TestBase): assert len(s) == ref_count assert len(s|s) == ref_count - def test_heads(self): - for head in self.rorepo.heads: + @with_rw_repo('HEAD', bare=False) + def test_heads(self, rwrepo): + for head in rwrepo.heads: assert head.name assert head.path assert "refs/heads" in head.path @@ -72,6 +73,23 @@ class TestRefs(TestBase): cur_object = head.object assert prev_object == cur_object # represent the same git object assert prev_object is not cur_object # but are different instances + + writer = head.config_writer() + tv = "testopt" + writer.set_value(tv, 1) + assert writer.get_value(tv) == 1 + del(writer) + assert head.config_reader().get_value(tv) == 1 + head.config_writer().remove_option(tv) + + # after the clone, we might still have a tracking branch setup + head.set_tracking_branch(None) + assert head.tracking_branch() is None + remote_ref = rwrepo.remotes[0].refs[0] + assert head.set_tracking_branch(remote_ref) is head + assert head.tracking_branch() == remote_ref + head.set_tracking_branch(None) + assert head.tracking_branch() is None # END for each head def test_refs(self): @@ -208,6 +226,8 @@ class TestRefs(TestBase): refs = remote.refs RemoteReference.delete(rw_repo, *refs) remote_refs_so_far += len(refs) + for ref in refs: + assert ref.remote_name == remote.name # END for each ref to delete assert remote_refs_so_far -- cgit v1.2.3 From 21b4db556619db2ef25f0e0d90fef7e38e6713e5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 11:27:23 +0100 Subject: Improved efficiency of the submodule.update process, improved test --- test/git/test_submodule.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 5b1cad6c..40836e1b 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -82,6 +82,8 @@ class TestSubmodule(TestBase): # TEST TODO: if a path in the gitmodules file, but not in the index, it raises + # TEST UPDATE + ############## # module retrieval is not always possible if rwrepo.bare: self.failUnlessRaises(InvalidGitRepositoryError, sm.module) @@ -106,6 +108,9 @@ class TestSubmodule(TestBase): assert isinstance(sm.module(), git.Repo) assert sm.module().working_tree_dir == sm.module_path() + # we should have setup a tracking branch, which is also active + assert sm.module().head.ref.tracking_branch() is not None + # delete the whole directory and re-initialize shutil.rmtree(sm.module_path()) sm.update(recursive=False) @@ -119,10 +124,12 @@ class TestSubmodule(TestBase): csm.config_writer().set_value('url', new_csm_path) assert csm.url == new_csm_path - # update recuesively again sm.update(recursive=True) + # tracking branch once again + csm.module().head.ref.tracking_branch() is not None + # this flushed in a sub-submodule assert len(list(rwrepo.iter_submodules())) == 2 # END handle bare mode -- cgit v1.2.3 From 78d2cd65b8b778f3b0cfef5268b0684314ca22ef Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 12:11:29 +0100 Subject: implemented update to_last_revision option including test. Its now possible to update submodules such as svn-externals --- test/git/test_submodule.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 40836e1b..9849a50f 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -132,6 +132,29 @@ class TestSubmodule(TestBase): # this flushed in a sub-submodule assert len(list(rwrepo.iter_submodules())) == 2 + + + # reset both heads to the previous version, verify that to_latest_revision works + for repo in (csm.module(), sm.module()): + repo.head.reset('HEAD~1', working_tree=1) + # END for each repo to reset + + sm.update(recursive=True, to_latest_revision=True) + for repo in (sm.module(), csm.module()): + assert repo.head.commit == repo.head.ref.tracking_branch().commit + # END for each repo to check + + # if the head is detached, it still works ( but warns ) + smref = sm.module().head.ref + sm.module().head.ref = 'HEAD~1' + # if there is no tracking branch, we get a warning as well + csm_tracking_branch = csm.module().head.ref.tracking_branch() + csm.module().head.ref.set_tracking_branch(None) + sm.update(recursive=True, to_latest_revision=True) + + # undo the changes + sm.module().head.ref = smref + csm.module().head.ref.set_tracking_branch(csm_tracking_branch) # END handle bare mode -- cgit v1.2.3 From 3d061a1a506b71234f783628ba54a7bdf79bbce9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 17:16:44 +0100 Subject: Implemented deletion of submodules including proper tests --- test/git/test_submodule.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 9849a50f..4be7e966 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -87,6 +87,7 @@ class TestSubmodule(TestBase): # module retrieval is not always possible if rwrepo.bare: self.failUnlessRaises(InvalidGitRepositoryError, sm.module) + self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) else: # its not checked out in our case self.failUnlessRaises(InvalidGitRepositoryError, sm.module) @@ -155,6 +156,55 @@ class TestSubmodule(TestBase): # undo the changes sm.module().head.ref = smref csm.module().head.ref.set_tracking_branch(csm_tracking_branch) + + # REMOVAL OF REPOSITOTRY + ######################## + # must delete something + self.failUnlessRaises(ValueError, csm.remove, module=False, configuration=False) + # We have modified the configuration, hence the index is dirty, and the + # deletion will fail + # NOTE: As we did a few updates in the meanwhile, the indices where reset + # Hence we restore some changes + sm.config_writer().set_value("somekey", "somevalue") + csm.config_writer().set_value("okey", "ovalue") + self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) + # if we remove the dirty index, it would work + sm.module().index.reset() + # still, we have the file modified + self.failUnlessRaises(InvalidGitRepositoryError, sm.remove, dry_run=True) + sm.module().index.reset(working_tree=True) + + # this would work + sm.remove(dry_run=True) + assert sm.module_exists() + sm.remove(force=True, dry_run=True) + assert sm.module_exists() + + # but ... we have untracked files in the child submodule + fn = join_path_native(csm.module().working_tree_dir, "newfile") + open(fn, 'w').write("hi") + self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) + + # forcibly delete the child repository + csm.remove(force=True) + assert not csm.exists() + assert not csm.module_exists() + assert len(sm.children()) == 0 + # now we have a changed index, as configuration was altered. + # fix this + sm.module().index.reset(working_tree=True) + + # now delete only the module of the main submodule + assert sm.module_exists() + sm.remove(configuration=False) + assert sm.exists() + assert not sm.module_exists() + assert sm.config_reader().get_value('url') + + # delete the rest + sm.remove() + assert not sm.exists() + assert not sm.module_exists() # END handle bare mode -- cgit v1.2.3 From 98e6edb546116cd98abdc3b37c6744e859bbde5c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 19:01:27 +0100 Subject: Initial implementation of submodule.add without any tests. These are to come next --- test/git/test_submodule.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 4be7e966..6172fed5 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -50,16 +50,18 @@ class TestSubmodule(TestBase): # test config_reader/writer methods sm.config_reader() + new_smclone_path = None # keep custom paths for later + new_csmclone_path = None # if rwrepo.bare: self.failUnlessRaises(InvalidGitRepositoryError, sm.config_writer) else: writer = sm.config_writer() # for faster checkout, set the url to the local path - new_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path)) - writer.set_value('url', new_path) + new_smclone_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path)) + writer.set_value('url', new_smclone_path) del(writer) - assert sm.config_reader().get_value('url') == new_path - assert sm.url == new_path + assert sm.config_reader().get_value('url') == new_smclone_path + assert sm.url == new_smclone_path # END handle bare repo smold.config_reader() @@ -88,6 +90,7 @@ class TestSubmodule(TestBase): if rwrepo.bare: self.failUnlessRaises(InvalidGitRepositoryError, sm.module) self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) + self.failUnlessRaises(InvalidGitRepositoryError, sm.add, rwrepo, 'here', 'there') else: # its not checked out in our case self.failUnlessRaises(InvalidGitRepositoryError, sm.module) @@ -121,9 +124,9 @@ class TestSubmodule(TestBase): assert not csm.module_exists() # adjust the path of the submodules module to point to the local destination - new_csm_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path, csm.path)) - csm.config_writer().set_value('url', new_csm_path) - assert csm.url == new_csm_path + new_csmclone_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path, csm.path)) + csm.config_writer().set_value('url', new_csmclone_path) + assert csm.url == new_csmclone_path # update recuesively again sm.update(recursive=True) @@ -205,6 +208,11 @@ class TestSubmodule(TestBase): sm.remove() assert not sm.exists() assert not sm.module_exists() + + # ADD NEW SUBMODULE + ################### + # raise if url does not match remote url of existing repo + # END handle bare mode -- cgit v1.2.3 From 33964afb47ce3af8a32e6613b0834e5f94bdfe68 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 21:07:33 +0100 Subject: Added tests for all failure modes of submodule add ( except for one ), and fixed a few issues on the way --- test/git/test_submodule.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 6172fed5..b66c4d9f 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -99,6 +99,21 @@ class TestSubmodule(TestBase): # currently there is only one submodule assert len(list(rwrepo.iter_submodules())) == 1 + # TEST ADD + ########### + # preliminary tests + # adding existing returns exactly the existing + sma = Submodule.add(rwrepo, sm.name, sm.path) + assert sma.path == sm.path + + # no url and no module at path fails + self.failUnlessRaises(ValueError, Submodule.add, rwrepo, "newsubm", "pathtorepo", url=None) + + # TODO: Test no remote url in existing repository + + # CONTINUE UPDATE + ################# + # lets update it - its a recursive one too newdir = os.path.join(sm.module_path(), 'dir') os.makedirs(newdir) @@ -112,6 +127,15 @@ class TestSubmodule(TestBase): assert isinstance(sm.module(), git.Repo) assert sm.module().working_tree_dir == sm.module_path() + # INTERLEAVE ADD TEST + ##################### + # url must match the one in the existing repository ( if submodule name suggests a new one ) + # or we raise + self.failUnlessRaises(ValueError, Submodule.add, rwrepo, "newsubm", sm.path, "git://someurl/repo.git") + + + # CONTINUE UPDATE + ################# # we should have setup a tracking branch, which is also active assert sm.module().head.ref.tracking_branch() is not None -- cgit v1.2.3 From 7b3ef45167e1c2f7d1b7507c13fcedd914f87da9 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 16 Nov 2010 21:21:09 +0100 Subject: The submodule's branch is now a branch instance, not a plain string anymore --- test/git/test_submodule.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index b66c4d9f..a8f8f2b7 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -34,7 +34,7 @@ class TestSubmodule(TestBase): assert sm.path == 'lib/git/ext/gitdb' assert sm.path == sm.name # for now, this is True assert sm.url == 'git://gitorious.org/git-python/gitdb.git' - assert sm.branch == 'master' # its unset in this case + assert sm.branch.name == 'master' # its unset in this case assert sm.parent_commit == rwrepo.head.commit # size is invalid self.failUnlessRaises(ValueError, getattr, sm, 'size') -- cgit v1.2.3 From ef48ca5f54fe31536920ec4171596ff8468db5fe Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 00:28:57 +0100 Subject: Added rest of submodule.add test code which should be pretty much 100% coverage for it --- test/git/test_submodule.py | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index a8f8f2b7..6432fcaf 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -32,7 +32,7 @@ class TestSubmodule(TestBase): assert len(Submodule.list_items(rwrepo, self.k_no_subm_tag)) == 0 assert sm.path == 'lib/git/ext/gitdb' - assert sm.path == sm.name # for now, this is True + assert sm.path == sm.name # for now, this is True assert sm.url == 'git://gitorious.org/git-python/gitdb.git' assert sm.branch.name == 'master' # its unset in this case assert sm.parent_commit == rwrepo.head.commit @@ -109,8 +109,6 @@ class TestSubmodule(TestBase): # no url and no module at path fails self.failUnlessRaises(ValueError, Submodule.add, rwrepo, "newsubm", "pathtorepo", url=None) - # TODO: Test no remote url in existing repository - # CONTINUE UPDATE ################# @@ -123,6 +121,7 @@ class TestSubmodule(TestBase): os.rmdir(newdir) assert sm.update() is sm + sm_repopath = sm.path # cache for later assert sm.module_exists() assert isinstance(sm.module(), git.Repo) assert sm.module().working_tree_dir == sm.module_path() @@ -146,6 +145,7 @@ class TestSubmodule(TestBase): assert len(sm.children()) == 1 # its not checked out yet csm = sm.children()[0] assert not csm.module_exists() + csm_repopath = csm.path # adjust the path of the submodules module to point to the local destination new_csmclone_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path, csm.path)) @@ -233,10 +233,44 @@ class TestSubmodule(TestBase): assert not sm.exists() assert not sm.module_exists() + assert len(rwrepo.submodules) == 0 + # ADD NEW SUBMODULE ################### - # raise if url does not match remote url of existing repo + # add a simple remote repo - trailing slashes are no problem + smid = "newsub" + osmid = "othersub" + nsm = Submodule.add(rwrepo, smid, sm_repopath, new_smclone_path, None, no_checkout=True) + assert nsm.name == smid + assert nsm.module_exists() + assert nsm.exists() + # its not checked out + assert not os.path.isfile(join_path_native(nsm.module().working_tree_dir, Submodule.k_modules_file)) + assert len(rwrepo.submodules) == 1 + + # add another submodule, but into the root, not as submodule + osm = Submodule.add(rwrepo, osmid, csm_repopath, new_csmclone_path, Submodule.k_head_default) + assert osm != nsm + assert osm.module_exists() + assert osm.exists() + assert os.path.isfile(join_path_native(osm.module().working_tree_dir, 'setup.py')) + + assert len(rwrepo.submodules) == 2 + + # commit the changes, just to finalize the operation + rwrepo.index.commit("my submod commit") + assert len(rwrepo.submodules) == 2 + # if a submodule's repo has no remotes, it can't be added without an explicit url + osmod = osm.module() + # needs update as the head changed, it thinks its in the history + # of the repo otherwise + osm._parent_commit = rwrepo.head.commit + osm.remove(module=False) + for remote in osmod.remotes: + remote.remove(osmod, remote.name) + assert not osm.exists() + self.failUnlessRaises(ValueError, Submodule.add, rwrepo, osmid, csm_repopath, url=None) # END handle bare mode -- cgit v1.2.3 From a1e6234c27abf041e4c8cd1a799950e7cd9104f6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 15:24:48 +0100 Subject: Inital implementation of Submodule.move including a very simple and to-be-improved test --- test/git/test_repo.py | 9 ++++++++ test/git/test_submodule.py | 54 ++++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 31 deletions(-) (limited to 'test') diff --git a/test/git/test_repo.py b/test/git/test_repo.py index 3a59f05e..2acccced 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -562,3 +562,12 @@ class TestRepo(TestBase): assert isinstance(self.rorepo.submodule("lib/git/ext/gitdb"), Submodule) self.failUnlessRaises(ValueError, self.rorepo.submodule, "doesn't exist") + + @with_rw_repo('HEAD', bare=False) + def test_submodule_update(self, rwrepo): + # fails in bare mode + rwrepo._bare = True + self.failUnlessRaises(InvalidGitRepositoryError, rwrepo.submodule_update) + rwrepo._bare = False + + diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 6432fcaf..20826f70 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -36,8 +36,8 @@ class TestSubmodule(TestBase): assert sm.url == 'git://gitorious.org/git-python/gitdb.git' assert sm.branch.name == 'master' # its unset in this case assert sm.parent_commit == rwrepo.head.commit - # size is invalid - self.failUnlessRaises(ValueError, getattr, sm, 'size') + # size is always 0 + assert sm.size == 0 # some commits earlier we still have a submodule, but its at a different commit smold = Submodule.iter_items(rwrepo, self.k_subm_changed).next() @@ -240,7 +240,7 @@ class TestSubmodule(TestBase): # add a simple remote repo - trailing slashes are no problem smid = "newsub" osmid = "othersub" - nsm = Submodule.add(rwrepo, smid, sm_repopath, new_smclone_path, None, no_checkout=True) + nsm = Submodule.add(rwrepo, smid, sm_repopath, new_smclone_path+"/", None, no_checkout=True) assert nsm.name == smid assert nsm.module_exists() assert nsm.exists() @@ -261,11 +261,29 @@ class TestSubmodule(TestBase): rwrepo.index.commit("my submod commit") assert len(rwrepo.submodules) == 2 - # if a submodule's repo has no remotes, it can't be added without an explicit url - osmod = osm.module() # needs update as the head changed, it thinks its in the history # of the repo otherwise + nsm._parent_commit = rwrepo.head.commit osm._parent_commit = rwrepo.head.commit + + # MOVE MODULE + ############# + # renaming to the same path does nothing + assert nsm.move(sm.path) is nsm + + # rename a module + nmp = join_path_native("new", "module", "dir") + "/" # new module path + assert nsm.move(nmp) is nsm + nmp = nmp[:-1] # cut last / + assert nsm.path == nmp + assert rwrepo.submodules[0].path == nmp + + + # REMOVE 'EM ALL + ################ + # if a submodule's repo has no remotes, it can't be added without an explicit url + osmod = osm.module() + osm.remove(module=False) for remote in osmod.remotes: remote.remove(osmod, remote.name) @@ -273,35 +291,9 @@ class TestSubmodule(TestBase): self.failUnlessRaises(ValueError, Submodule.add, rwrepo, osmid, csm_repopath, url=None) # END handle bare mode - # Error if there is no submodule file here self.failUnlessRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True) - # TODO: Handle bare/unbare - # latest submodules write changes into the .gitmodules files - - # uncached path/url - retrieves information from .gitmodules file - - # index stays up-to-date with the working tree .gitmodules file - - # changing the root_tree yields new values when querying them (i.e. cache is cleared) - - - - - # set_parent_commit fails if tree has no gitmodule file - - - - if rwrepo.bare: - # module fails - pass - else: - # get the module repository - pass - # END bare handling - - # Writing of historical submodule configurations must not work @with_rw_repo(k_subm_current) def test_base_rw(self, rwrepo): -- cgit v1.2.3 From 609a46a72764dc71104aa5d7b1ca5f53d4237a75 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 17:15:24 +0100 Subject: submodule: removed module_path method as it is implemented in the abspath property alrdeady Improved submodule move tests --- test/git/test_submodule.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 20826f70..212b1e1d 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -113,7 +113,7 @@ class TestSubmodule(TestBase): ################# # lets update it - its a recursive one too - newdir = os.path.join(sm.module_path(), 'dir') + newdir = os.path.join(sm.abspath, 'dir') os.makedirs(newdir) # update fails if the path already exists non-empty @@ -124,7 +124,7 @@ class TestSubmodule(TestBase): sm_repopath = sm.path # cache for later assert sm.module_exists() assert isinstance(sm.module(), git.Repo) - assert sm.module().working_tree_dir == sm.module_path() + assert sm.module().working_tree_dir == sm.abspath # INTERLEAVE ADD TEST ##################### @@ -139,7 +139,7 @@ class TestSubmodule(TestBase): assert sm.module().head.ref.tracking_branch() is not None # delete the whole directory and re-initialize - shutil.rmtree(sm.module_path()) + shutil.rmtree(sm.abspath) sm.update(recursive=False) assert len(list(rwrepo.iter_submodules())) == 2 assert len(sm.children()) == 1 # its not checked out yet @@ -273,11 +273,29 @@ class TestSubmodule(TestBase): # rename a module nmp = join_path_native("new", "module", "dir") + "/" # new module path + pmp = nsm.path + abspmp = nsm.abspath assert nsm.move(nmp) is nsm nmp = nmp[:-1] # cut last / assert nsm.path == nmp assert rwrepo.submodules[0].path == nmp + # move it back - but there is a file now - this doesn't work + # as the empty directories where removed. + self.failUnlessRaises(IOError, open, abspmp, 'w') + + mpath = 'newsubmodule' + absmpath = join_path_native(rwrepo.working_tree_dir, mpath) + open(absmpath, 'w').write('') + self.failUnlessRaises(ValueError, nsm.move, mpath) + os.remove(absmpath) + + # now it works, as we just move it back + nsm.move(pmp) + assert nsm.path == pmp + assert rwrepo.submodules[0].path == pmp + + # TODO lowprio: test remaining exceptions ... for now its okay, the code looks right # REMOVE 'EM ALL ################ -- cgit v1.2.3 From 7cc4d748a132377ffe63534e9777d7541a3253c5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 21:33:33 +0100 Subject: repo: Added create_submodule method which fits into the tradition of offering a create_* method for most important entities. Moved implementation of smart update method to the RootModule implementation, where it may do special things without requiring an interface for everything --- test/git/test_repo.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'test') diff --git a/test/git/test_repo.py b/test/git/test_repo.py index 2acccced..fb6e1450 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -570,4 +570,9 @@ class TestRepo(TestBase): self.failUnlessRaises(InvalidGitRepositoryError, rwrepo.submodule_update) rwrepo._bare = False + # test create submodule + sm = rwrepo.submodules[0] + sm = rwrepo.create_submodule("my_new_sub", "some_path", join_path_native(self.rorepo.working_tree_dir, sm.path)) + assert isinstance(sm, Submodule) + -- cgit v1.2.3 From 1687283c13caf7ff8d1959591541dff6a171ca1e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 17 Nov 2010 22:38:10 +0100 Subject: RootModule.update: initial implementation of update method, which should be able to handle submodule removals, additions, path changes and branch changes. All this still needs to be tested though --- test/git/test_submodule.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 212b1e1d..8430f4bc 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -202,7 +202,7 @@ class TestSubmodule(TestBase): sm.module().index.reset(working_tree=True) # this would work - sm.remove(dry_run=True) + assert sm.remove(dry_run=True) is sm assert sm.module_exists() sm.remove(force=True, dry_run=True) assert sm.module_exists() @@ -213,7 +213,7 @@ class TestSubmodule(TestBase): self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) # forcibly delete the child repository - csm.remove(force=True) + assert csm.remove(force=True) is csm assert not csm.exists() assert not csm.module_exists() assert len(sm.children()) == 0 @@ -263,8 +263,8 @@ class TestSubmodule(TestBase): # needs update as the head changed, it thinks its in the history # of the repo otherwise - nsm._parent_commit = rwrepo.head.commit - osm._parent_commit = rwrepo.head.commit + nsm.set_parent_commit(rwrepo.head.commit) + osm.set_parent_commit(rwrepo.head.commit) # MOVE MODULE ############# -- cgit v1.2.3 From 7a320abc52307b4d4010166bd899ac75024ec9a7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 09:20:15 +0100 Subject: commit: when creating a new commit and advancing the head, it will now write the ORIG_HEAD reference as well --- test/git/test_index.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index b5600eeb..29a7404d 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -409,6 +409,7 @@ class TestIndex(TestBase): commit_message = "commit default head" new_commit = index.commit(commit_message, head=False) + assert cur_commit != new_commit assert new_commit.author.name == uname assert new_commit.author.email == umail assert new_commit.committer.name == uname @@ -421,6 +422,7 @@ class TestIndex(TestBase): # same index, no parents commit_message = "index without parents" commit_no_parents = index.commit(commit_message, parent_commits=list(), head=True) + assert SymbolicReference(rw_repo, 'ORIG_HEAD').commit == cur_commit assert commit_no_parents.message == commit_message assert len(commit_no_parents.parents) == 0 assert cur_head.commit == commit_no_parents -- cgit v1.2.3 From 82849578e61a7dfb47fc76dcbe18b1e3b6a36951 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 10:40:16 +0100 Subject: ORIG_HEAD handling is now implemented in the ref-class itself, instead of being a special case of the commit method; includes tests util: Fixed iterable lists, which broke due to an incorrectly implemented __contains__ method --- test/git/test_refs.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'test') diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 4cfd952e..fa26bae9 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -92,6 +92,37 @@ 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 + + def test_refs(self): types_found = set() for ref in self.rorepo.refs: -- cgit v1.2.3 From 0c1834134ce177cdbd30a56994fcc4bf8f5be8b2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 11:41:16 +0100 Subject: Added test-setup which can test all aspects of the (smart) update method --- test/git/test_repo.py | 2 ++ test/git/test_submodule.py | 46 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/git/test_repo.py b/test/git/test_repo.py index fb6e1450..a6047bf5 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -575,4 +575,6 @@ class TestRepo(TestBase): sm = rwrepo.create_submodule("my_new_sub", "some_path", join_path_native(self.rorepo.working_tree_dir, sm.path)) assert isinstance(sm, Submodule) + # note: the rest of this functionality is tested in test_submodule + diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 8430f4bc..d2cd7fbe 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -321,11 +321,13 @@ class TestSubmodule(TestBase): def test_base_bare(self, rwrepo): self._do_base_tests(rwrepo) - def test_root_module(self): + @with_rw_repo(k_subm_current, bare=False) + def test_root_module(self, rwrepo): # Can query everything without problems rm = RootModule(self.rorepo) assert rm.module() is self.rorepo + # try attributes rm.binsha rm.mode rm.path @@ -339,8 +341,46 @@ class TestSubmodule(TestBase): rm.config_writer() # deep traversal gitdb / async - assert len(list(rm.traverse())) == 2 + rsms = list(rm.traverse()) + assert len(rsms) == 2 # gitdb and async, async being a child of gitdb - # cannot set the parent commit as repo name doesn't exist + # cannot set the parent commit as root module's path didn't exist self.failUnlessRaises(ValueError, rm.set_parent_commit, 'HEAD') + # TEST UPDATE + ############# + # setup commit which remove existing, add new and modify existing submodules + rm = RootModule(rwrepo) + assert len(rm.children()) == 1 + + # modify path + sm = rm.children()[0] + pp = "path/prefix" + sm.config_writer().set_value('path', join_path_native(pp, sm.path)) + cpathchange = rwrepo.index.commit("changed sm path") + + # add submodule + nsmn = "newsubmodule" + nsmp = "submrepo" + nsm = Submodule.add(rwrepo, nsmn, nsmp, url=join_path_native(self.rorepo.working_tree_dir, rsms[0].path, rsms[1].path)) + csmadded = rwrepo.index.commit("Added submodule") + + # remove submodule - the previous one + sm.set_parent_commit(csmadded) + assert not sm.remove().exists() + csmremoved = rwrepo.index.commit("Removed submodule") + + # change url - to the first repository, this way we have a fast checkout, and a completely different + # repository at the different url + nsm.set_parent_commit(csmremoved) + nsm.config_writer().set_value('url', join_path_native(self.rorepo.working_tree_dir, rsms[0].path)) + csmpathchange = rwrepo.index.commit("changed url") + + # change branch + nsm.set_parent_commit(csmpathchange) + # the branch used here is an old failure branch which should ideally stay ... lets see how long that works ;) + nbn = 'pack_offset_cache' + assert nsm.branch.name != nbn + nsm.config_writer().set_value(Submodule.k_head_option, nbn) + csmbranchchange = rwrepo.index.commit("changed branch") + -- cgit v1.2.3 From c0990b2a6dd2e777b46c1685ddb985b3c0ef59a2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 17:09:32 +0100 Subject: first update test succeeds, so it verifies that existing repositories can be moved later if the configuration changed, and actually it also verifies that the url-change is handled correctly (as we changed the url from the default to the local path) --- test/git/test_submodule.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index d2cd7fbe..ad09f483 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -42,7 +42,7 @@ class TestSubmodule(TestBase): # some commits earlier we still have a submodule, but its at a different commit smold = Submodule.iter_items(rwrepo, self.k_subm_changed).next() assert smold.binsha != sm.binsha - assert smold != sm + assert smold == sm # the name is still the same # force it to reread its information del(smold._url) @@ -268,6 +268,9 @@ class TestSubmodule(TestBase): # MOVE MODULE ############# + # invalid inptu + self.failUnlessRaises(ValueError, nsm.move, 'doesntmatter', module=False, configuration=False) + # renaming to the same path does nothing assert nsm.move(sm.path) is nsm @@ -353,11 +356,39 @@ class TestSubmodule(TestBase): rm = RootModule(rwrepo) assert len(rm.children()) == 1 - # modify path + # modify path without modifying the index entry + # ( which is what the move method would do properly ) sm = rm.children()[0] pp = "path/prefix" - sm.config_writer().set_value('path', join_path_native(pp, sm.path)) - cpathchange = rwrepo.index.commit("changed sm path") + fp = join_path_native(pp, sm.path) + prep = sm.path + assert not sm.module_exists() # was never updated after rwrepo's clone + + # assure we clone from a local source + sm.config_writer().set_value('url', join_path_native(self.rorepo.working_tree_dir, sm.path)) + sm.update(recursive=False) + assert sm.module_exists() + sm.config_writer().set_value('path', fp) # change path to something with prefix AFTER url change + + # update fails as list_items in such a situations cannot work, as it cannot + # find the entry at the changed path + self.failUnlessRaises(InvalidGitRepositoryError, rm.update, recursive=False) + + # move it properly - doesn't work as it its path currently points to an indexentry + # which doesn't exist ( move it to some path, it doesn't matter here ) + self.failUnlessRaises(InvalidGitRepositoryError, sm.move, pp) + # reset the path(cache) to where it was, now it works + sm.path = prep + sm.move(fp, module=False) # leave it at the old location + + assert not sm.module_exists() + cpathchange = rwrepo.index.commit("changed sm path") # finally we can commit + + # update puts the module into place + rm.update(recursive=False) + sm.set_parent_commit(cpathchange) + assert sm.module_exists() + assert False # add submodule nsmn = "newsubmodule" -- cgit v1.2.3 From cf5eaddde33e983bc7b496f458bdd49154f6f498 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 20:44:21 +0100 Subject: Updated tests and implementation to verify functionality for handling submodule removals, as well as url changes --- test/git/test_submodule.py | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index ad09f483..5e209f1b 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -358,6 +358,7 @@ class TestSubmodule(TestBase): # modify path without modifying the index entry # ( which is what the move method would do properly ) + #================================================== sm = rm.children()[0] pp = "path/prefix" fp = join_path_native(pp, sm.path) @@ -388,26 +389,58 @@ class TestSubmodule(TestBase): rm.update(recursive=False) sm.set_parent_commit(cpathchange) assert sm.module_exists() - assert False # add submodule + #================ nsmn = "newsubmodule" nsmp = "submrepo" nsm = Submodule.add(rwrepo, nsmn, nsmp, url=join_path_native(self.rorepo.working_tree_dir, rsms[0].path, rsms[1].path)) csmadded = rwrepo.index.commit("Added submodule") + nsm.set_parent_commit(csmadded) + assert nsm.module_exists() + # in our case, the module should not exist, which happens if we update a parent + # repo and a new submodule comes into life + nsm.remove(configuration=False, module=True) + assert not nsm.module_exists() and nsm.exists() + + rm.update(recursive=False) + assert nsm.module_exists() + + # remove submodule - the previous one + #==================================== sm.set_parent_commit(csmadded) - assert not sm.remove().exists() + smp = sm.abspath + assert not sm.remove(module=False).exists() + assert os.path.isdir(smp) # module still exists csmremoved = rwrepo.index.commit("Removed submodule") - # change url - to the first repository, this way we have a fast checkout, and a completely different + # an update will remove the module + rm.update(recursive=False) + assert not os.path.isdir(smp) + + + # change url + #============= + # to the first repository, this way we have a fast checkout, and a completely different # repository at the different url nsm.set_parent_commit(csmremoved) - nsm.config_writer().set_value('url', join_path_native(self.rorepo.working_tree_dir, rsms[0].path)) + nsmurl = join_path_native(self.rorepo.working_tree_dir, rsms[0].path) + nsm.config_writer().set_value('url', nsmurl) csmpathchange = rwrepo.index.commit("changed url") + nsm.set_parent_commit(csmpathchange) + + prev_commit = nsm.module().head.commit + rm.update(recursive=False) + assert nsm.module().remotes.origin.url == nsmurl + # head changed, as the remote url and its commit changed + assert prev_commit != nsm.module().head.commit + + assert False # change branch + #================= nsm.set_parent_commit(csmpathchange) # the branch used here is an old failure branch which should ideally stay ... lets see how long that works ;) nbn = 'pack_offset_cache' @@ -415,3 +448,8 @@ class TestSubmodule(TestBase): nsm.config_writer().set_value(Submodule.k_head_option, nbn) csmbranchchange = rwrepo.index.commit("changed branch") + + # recursive update + # ================= + # finally we recursively update a module, just to run the code at least once + -- cgit v1.2.3 From 3f2d76ba8e6d004ff5849ed8c7c34f6a4ac2e1e3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 21:36:01 +0100 Subject: Added test for branch changes - it appears to work well, at least as far as the restricted tests are concerned --- test/git/test_submodule.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index 5e209f1b..dbc2ef08 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -437,16 +437,34 @@ class TestSubmodule(TestBase): # head changed, as the remote url and its commit changed assert prev_commit != nsm.module().head.commit - assert False + # add the submodule's changed commit to the index, which is what the + # user would do + # beforehand, update our instance's binsha with the new one + nsm.binsha = nsm.module().head.commit.binsha + rwrepo.index.add([nsm]) # change branch #================= - nsm.set_parent_commit(csmpathchange) - # the branch used here is an old failure branch which should ideally stay ... lets see how long that works ;) - nbn = 'pack_offset_cache' - assert nsm.branch.name != nbn - nsm.config_writer().set_value(Submodule.k_head_option, nbn) - csmbranchchange = rwrepo.index.commit("changed branch") + # we only have one branch, so we switch to a virtual one, and back + # to the current one to trigger the difference + cur_branch = nsm.branch + nsmm = nsm.module() + prev_commit = nsmm.head.commit + for branch in ("some_virtual_branch", cur_branch.name): + nsm.config_writer().set_value(Submodule.k_head_option, branch) + csmbranchchange = rwrepo.index.commit("changed branch to %s" % branch) + nsm.set_parent_commit(csmbranchchange) + # END for each branch to change + + # Lets remove our tracking branch to simulate some changes + nsmmh = nsmm.head + assert nsmmh.ref.tracking_branch() is None # never set it up until now + assert not nsmmh.is_detached + + rm.update(recursive=False) + + assert nsmmh.ref.tracking_branch() is not None + assert not nsmmh.is_detached # recursive update -- cgit v1.2.3 From ebe8f644e751c1b2115301c1a961bef14d2cce89 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 22:11:06 +0100 Subject: Added test for the recursive code path. --- test/git/test_submodule.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index dbc2ef08..b2b61f39 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -394,7 +394,8 @@ class TestSubmodule(TestBase): #================ nsmn = "newsubmodule" nsmp = "submrepo" - nsm = Submodule.add(rwrepo, nsmn, nsmp, url=join_path_native(self.rorepo.working_tree_dir, rsms[0].path, rsms[1].path)) + async_url = join_path_native(self.rorepo.working_tree_dir, rsms[0].path, rsms[1].path) + nsm = Submodule.add(rwrepo, nsmn, nsmp, url=async_url) csmadded = rwrepo.index.commit("Added submodule") nsm.set_parent_commit(csmadded) assert nsm.module_exists() @@ -466,8 +467,16 @@ class TestSubmodule(TestBase): assert nsmmh.ref.tracking_branch() is not None assert not nsmmh.is_detached - # recursive update # ================= # finally we recursively update a module, just to run the code at least once + # remove the module so that it has more work + assert len(nsm.children()) == 1 + assert nsm.exists() and nsm.module_exists() and len(nsm.children()) == 1 + # assure we pull locally only + nsmc = nsm.children()[0] + nsmc.config_writer().set_value('url', async_url) + rm.update(recursive=True) + + assert len(nsm.children()) == 1 and nsmc.module_exists() -- cgit v1.2.3 From 9519f186ce757cdba217f222c95c20033d00f91d Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 18 Nov 2010 23:10:23 +0100 Subject: Fixed all imports, refactoring appears to be complete --- test/git/test_submodule.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py index b2b61f39..e7807dcd 100644 --- a/test/git/test_submodule.py +++ b/test/git/test_submodule.py @@ -3,7 +3,8 @@ from test.testlib import * from git.exc import * -from git.objects.submodule import * +from git.objects.submodule.base import Submodule +from git.objects.submodule.root import RootModule from git.util import to_native_path_linux, join_path_native import shutil import git @@ -315,7 +316,6 @@ class TestSubmodule(TestBase): # Error if there is no submodule file here self.failUnlessRaises(IOError, Submodule._config_parser, rwrepo, rwrepo.commit(self.k_no_subm_tag), True) - @with_rw_repo(k_subm_current) def test_base_rw(self, rwrepo): self._do_base_tests(rwrepo) -- cgit v1.2.3