From a10aa36bc6a82bd50df6f3df7d6b7ce04a7070f1 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 10:42:26 +0200 Subject: Renamed Index to IndexFile, adjusted tests, it will only operate on physical files, not on streams, as Indices are not streamed by any git command ( at least not in raw format ) --- test/git/test_index.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index 7bc2ad7e..6fd3133a 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -12,9 +12,9 @@ import tempfile class TestTree(TestBase): - def test_base(self): + def test_index_file_base(self): # read from file - index = Index.from_file(self.rorepo, fixture_path("index")) + index = IndexFile(self.rorepo, fixture_path("index")) assert index.entries assert index.version > 0 @@ -27,20 +27,16 @@ class TestTree(TestBase): # END for each method # test stage - index_merge = Index.from_file(self.rorepo, fixture_path("index_merge")) + index_merge = IndexFile(self.rorepo, fixture_path("index_merge")) assert len(index_merge.entries) == 106 assert len(list(e for e in index_merge.entries.itervalues() if e.stage != 0 )) # write the data - it must match the original - index_output = os.tmpfile() - index_merge.write(index_output) - - index_output.seek(0) - assert index_output.read() == fixture("index_merge") - tmpfile = tempfile.mktemp() - Index.to_file(index_merge, tmpfile) - assert os.path.isfile(tmpfile) + index_merge.write(tmpfile) + fp = open(tmpfile, 'r') + assert fp.read() == fixture("index_merge") + fp.close() os.remove(tmpfile) def _cmp_tree_index(self, tree, index): @@ -55,23 +51,23 @@ class TestTree(TestBase): # END for each blob in tree assert num_blobs == len(index.entries) - def test_from_tree(self): + def test_index_file_from_tree(self): common_ancestor_sha = "5117c9c8a4d3af19a9958677e45cda9269de1541" cur_sha = "4b43ca7ff72d5f535134241e7c797ddc9c7a3573" other_sha = "39f85c4358b7346fee22169da9cad93901ea9eb9" # simple index from tree - base_index = Index.from_tree(self.rorepo, common_ancestor_sha) + base_index = IndexFile.from_tree(self.rorepo, common_ancestor_sha) assert base_index.entries self._cmp_tree_index(common_ancestor_sha, base_index) # merge two trees - its like a fast-forward - two_way_index = Index.from_tree(self.rorepo, common_ancestor_sha, cur_sha) + two_way_index = IndexFile.from_tree(self.rorepo, common_ancestor_sha, cur_sha) assert two_way_index.entries self._cmp_tree_index(cur_sha, two_way_index) # merge three trees - here we have a merge conflict - three_way_index = Index.from_tree(self.rorepo, common_ancestor_sha, cur_sha, other_sha) + three_way_index = IndexFile.from_tree(self.rorepo, common_ancestor_sha, cur_sha, other_sha) assert len(list(e for e in three_way_index.entries.values() if e.stage != 0)) @@ -102,9 +98,9 @@ class TestTree(TestBase): assert num_blobs == len(three_way_index.entries) @with_rw_repo('0.1.6') - def test_from_index_and_diff(self, rw_repo): + def test_index_file_diffing(self, rw_repo): # default Index instance points to our index - index = Index(rw_repo) + index = IndexFile(rw_repo) assert index.path is not None assert len(index.entries) -- cgit v1.2.1 From 3d3a24b22d340c62fafc0e75a349c0ffe34d99d7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 11:07:04 +0200 Subject: Added repo.index property including simple test, and additional ideas in the TODO list --- test/git/test_repo.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/git/test_repo.py b/test/git/test_repo.py index b02610f4..4995d901 100644 --- a/test/git/test_repo.py +++ b/test/git/test_repo.py @@ -170,7 +170,11 @@ class TestRepo(TestBase): def test_head(self): assert self.rorepo.head.reference.object == self.rorepo.active_branch.object - + + def test_index(self): + index = self.rorepo.index + assert isinstance(index, IndexFile) + def test_tag(self): assert self.rorepo.tag('refs/tags/0.1.5').commit -- cgit v1.2.1 From a7a4388eeaa4b6b94192dce67257a34c4a6cbd26 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 12:14:22 +0200 Subject: Added frame for IndexFile add/remove/commit methods and respective test markers --- test/git/test_index.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index 6fd3133a..36e57d5c 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -26,6 +26,11 @@ class TestTree(TestBase): val = getattr(entry, attr) # END for each method + # test update + entries = index.entries + assert isinstance(index.update(), IndexFile) + assert entries is not index.entries + # test stage index_merge = IndexFile(self.rorepo, fixture_path("index_merge")) assert len(index_merge.entries) == 106 @@ -140,3 +145,11 @@ class TestTree(TestBase): # against something unusual self.failUnlessRaises(ValueError, index.diff, int) + + self.fail( "Test IndexFile.reset" ) + + @with_rw_repo('0.1.6') + def test_index_mutation(self, rw_repo): + # add / remove / commit / Working Tree Handling + self.fail( "add, remove, commit, working tree handling" ) + -- cgit v1.2.1 From 2c23ca3cd9b9bbeaca1b79068dee1eae045be5b6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 14:46:18 +0200 Subject: refs: added create, delete and rename methods where appropriate. Tests are marked, implementation is needed for most of them --- test/git/test_refs.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test') diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 1562310a..2665d93b 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -108,3 +108,11 @@ class TestRefs(TestBase): # type check self.failUnlessRaises(ValueError, setattr, cur_head, "reference", "that") + + + self.fail("head creation") + self.fail("head renaming") + self.fail("head removal") + self.fail("tag creation") + self.fail("tag deletion") + self.fail("remote deletion") -- cgit v1.2.1 From ddc5496506f0484e4f1331261aa8782c7e606bf2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 15:22:07 +0200 Subject: Implemented head methods: create, delete, rename, including tests --- test/git/test_refs.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 2665d93b..ac213384 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -109,10 +109,39 @@ class TestRefs(TestBase): # type check self.failUnlessRaises(ValueError, setattr, cur_head, "reference", "that") + # head handling + commit = 'HEAD' + prev_head_commit = cur_head.commit + 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 cur_head.commit == prev_head_commit + assert isinstance(new_head, Head) + # already exists + self.failUnlessRaises(GitCommandError, Head.create, rw_repo, new_name) + + # force it + new_head = Head.create(rw_repo, new_name, actual_commit, force=True) + old_path = new_head.path + old_name = new_head.name + + assert new_head.rename("hello").name == "hello" + assert new_head.rename("hello/world").name == "hello/world" + assert new_head.rename(old_name).name == old_name and new_head.path == old_path + + # rename with force + tmp_head = Head.create(rw_repo, "tmphead") + self.failUnlessRaises(GitCommandError, tmp_head.rename, new_head) + tmp_head.rename(new_head, force=True) + assert tmp_head == new_head and tmp_head.object == new_head.object + + Head.delete(rw_repo, tmp_head) + 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 ;) + # END for each new head name + self.failUnlessRaises(TypeError, RemoteReference.create, rw_repo, "some_name") - self.fail("head creation") - self.fail("head renaming") - self.fail("head removal") self.fail("tag creation") self.fail("tag deletion") self.fail("remote deletion") -- cgit v1.2.1 From 1047b41e2e925617474e2e7c9927314f71ce7365 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 15:45:23 +0200 Subject: Added TagRefernce creation and deletion including tests Added RemoteReference deletion and test --- test/git/test_refs.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/git/test_refs.py b/test/git/test_refs.py index ac213384..88e8a21a 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -142,6 +142,43 @@ class TestRefs(TestBase): # END for each new head name self.failUnlessRaises(TypeError, RemoteReference.create, rw_repo, "some_name") - self.fail("tag creation") - self.fail("tag deletion") - self.fail("remote deletion") + # tag ref + tag_name = "1.0.2" + light_tag = TagReference.create(rw_repo, tag_name) + self.failUnlessRaises(GitCommandError, TagReference.create, rw_repo, tag_name) + light_tag = TagReference.create(rw_repo, tag_name, "HEAD~1", force = True) + assert isinstance(light_tag, TagReference) + assert light_tag.name == tag_name + assert light_tag.commit == cur_head.commit.parents[0] + assert light_tag.tag is None + + # tag with tag object + other_tag_name = "releases/1.0.2RC" + msg = "my mighty tag\nsecond line" + obj_tag = TagReference.create(rw_repo, other_tag_name, message=msg) + assert isinstance(obj_tag, TagReference) + assert obj_tag.name == other_tag_name + assert obj_tag.commit == cur_head.commit + assert obj_tag.tag is not None + + TagReference.delete(rw_repo, light_tag, obj_tag) + tags = rw_repo.tags + assert light_tag not in tags and obj_tag not in tags + + # remote deletion + remote_refs_so_far = 0 + remotes = rw_repo.remotes + assert remotes + for remote in remotes: + refs = remote.refs + RemoteReference.delete(rw_repo, *refs) + remote_refs_so_far += len(refs) + # END for each ref to delete + assert remote_refs_so_far + + for remote in remotes: + # remotes without references throw + self.failUnlessRaises(AssertionError, getattr, remote, 'refs') + # END for each remote + + self.fail("set commit using ref.commit = that") -- cgit v1.2.1 From 9b9776e88f7abb59cebac8733c04cccf6eee1c60 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 16:07:45 +0200 Subject: Refs can now set the reference they are pointing to in a controlled fashion by writing their ref file directly --- test/git/test_refs.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'test') 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 -- cgit v1.2.1 From 13a26d4f9c22695033040dfcd8c76fd94187035b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 17:55:33 +0200 Subject: Implemented index.reset method including test --- test/git/test_index.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index 36e57d5c..7236aad9 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -146,7 +146,33 @@ class TestTree(TestBase): # against something unusual self.failUnlessRaises(ValueError, index.diff, int) - self.fail( "Test IndexFile.reset" ) + # adjust the index to match an old revision + cur_branch = rw_repo.active_branch + cur_commit = cur_branch.commit + rev_head_parent = 'HEAD~1' + assert index.reset(rev_head_parent) is index + + assert cur_branch == rw_repo.active_branch + assert cur_commit == rw_repo.head.commit + + # there must be differences towards the working tree which is in the 'future' + assert index.diff(None) + + # reset the working copy as well to current head,to pull 'back' as well + new_data = "will be reverted" + file_path = os.path.join(rw_repo.git.git_dir, "CHANGES") + fp = open(file_path, "w") + fp.write(new_data) + fp.close() + index.reset(rev_head_parent, working_tree=True) + assert not index.diff(None) + assert cur_branch == rw_repo.active_branch + assert cur_commit == rw_repo.head.commit + fp = open(file_path) + try: + assert fp.read() != new_data + finally: + fp.close() @with_rw_repo('0.1.6') def test_index_mutation(self, rw_repo): -- cgit v1.2.1 From 0cd09bd306486028f5442c56ef2e947355a06282 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 21:49:13 +0200 Subject: index.remove implemented including throrough test --- test/git/test_index.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index 7236aad9..2f8fed32 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -9,6 +9,7 @@ from git import * import inspect import os import tempfile +import glob class TestTree(TestBase): @@ -174,8 +175,67 @@ class TestTree(TestBase): finally: fp.close() + + def _count_existing(self, repo, files): + existing = 0 + basedir = repo.git.git_dir + for f in files: + existing += os.path.isfile(os.path.join(basedir, f)) + # END for each deleted file + return existing + # END num existing helper + + + @with_rw_repo('0.1.6') def test_index_mutation(self, rw_repo): - # add / remove / commit / Working Tree Handling - self.fail( "add, remove, commit, working tree handling" ) + index = rw_repo.index + num_entries = len(index.entries) + # remove all of the files, provide a wild mix of paths, BaseIndexEntries, + # IndexEntries + def mixed_iterator(): + count = 0 + for entry in index.entries.itervalues(): + type_id = count % 4 + if type_id == 0: # path + yield entry.path + elif type_id == 1: # blob + yield Blob(rw_repo, entry.sha, entry.mode, entry.path) + elif type_id == 2: # BaseIndexEntry + yield BaseIndexEntry(entry[:4]) + elif type_id == 3: # IndexEntry + yield entry + else: + raise AssertionError("Invalid Type") + count += 1 + # END for each entry + # END mixed iterator + deleted_files = index.remove(mixed_iterator(), working_tree=False) + assert deleted_files + assert self._count_existing(rw_repo, deleted_files) == len(deleted_files) + assert len(index.entries) == 0 + + # reset the index to undo our changes + index.reset() + assert len(index.entries) == num_entries + + # remove with working copy + deleted_files = index.remove(mixed_iterator(), working_tree=True) + assert deleted_files + assert self._count_existing(rw_repo, deleted_files) == 0 + + # reset everything + index.reset(working_tree=True) + assert self._count_existing(rw_repo, deleted_files) == len(deleted_files) + + # invalid type + self.failUnlessRaises(TypeError, index.remove, [1]) + + # absolute path + deleted_files = index.remove([os.path.join(rw_repo.git.git_dir,"lib")], r=True) + assert len(deleted_files) > 1 + self.failUnlessRaises(ValueError, index.remove, ["/doesnt/exists"]) + + # re-add all files in lib + self.fail( "add, commit, working tree handling" ) -- cgit v1.2.1 From b999cae064fb6ac11a61a39856e074341baeefde Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 23:44:49 +0200 Subject: actor: added __eq__, __ne__ and __hash__ methods including simple test commit: Fixed long-standing issue during message parsing that would fail to parse properly in case we were created from data. Also it would strip white space from the messages although it shouldn't --- test/git/test_actor.py | 8 ++++++++ test/git/test_commit.py | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/git/test_actor.py b/test/git/test_actor.py index b7c2af7c..2941468d 100644 --- a/test/git/test_actor.py +++ b/test/git/test_actor.py @@ -13,6 +13,14 @@ class TestActor(object): a = Actor._from_string("Michael Trier ") assert_equal("Michael Trier", a.name) assert_equal("mtrier@example.com", a.email) + + # base type capabilities + assert a == a + assert not ( a != a ) + m = set() + m.add(a) + m.add(a) + assert len(m) == 1 def test_from_string_should_handle_just_name(self): a = Actor._from_string("Michael Trier") diff --git a/test/git/test_commit.py b/test/git/test_commit.py index c4ed4b72..da636a2b 100644 --- a/test/git/test_commit.py +++ b/test/git/test_commit.py @@ -16,6 +16,9 @@ class TestCommit(TestBase): assert_equal("Sebastian Thiel", commit.author.name) assert_equal("byronimo@gmail.com", commit.author.email) + assert commit.author == commit.committer + assert isinstance(commit.authored_date, int) and isinstance(commit.committed_date, int) + assert commit.message == "Added missing information to docstrings of commit and stats module" def test_stats(self): @@ -37,6 +40,14 @@ class TestCommit(TestBase): check_entries(d) # END for each stated file + # assure data is parsed properly + michael = Actor._from_string("Michael Trier ") + assert commit.author == michael + assert commit.committer == michael + assert commit.authored_date == 1210193388 + assert commit.committed_date == 1210193388 + assert commit.message == "initial project" + @patch_object(Git, '_call_process') def test_rev_list_bisect_all(self, git): """ @@ -52,7 +63,7 @@ class TestCommit(TestBase): bisect_all=True) assert_true(git.called) - commits = Commit._iter_from_process_or_stream(self.rorepo, ListProcessAdapter(revs)) + commits = Commit._iter_from_process_or_stream(self.rorepo, ListProcessAdapter(revs), True) expected_ids = ( 'cf37099ea8d1d8c7fbf9b6d12d7ec0249d3acb8b', '33ebe7acec14b25c5f84f35a664803fcab2f7781', -- cgit v1.2.1 From f9cec00938d9059882bb8eabdaf2f775943e00e5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 24 Oct 2009 00:08:33 +0200 Subject: index.commit: implemented initial version, but in fact some more changes are required to have a nice API. Tests are not yet fully done either --- test/git/test_index.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index 2f8fed32..0a5f4c35 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -236,6 +236,18 @@ class TestTree(TestBase): assert len(deleted_files) > 1 self.failUnlessRaises(ValueError, index.remove, ["/doesnt/exists"]) + # test committing + # commit changed index + cur_commit = rw_repo.head.commit + commit_message = "commit default head" + new_commit = index.commit(commit_message) + assert new_commit.message == commit_message + assert new_commit.parents[0] == cur_commit + + self.fail("commit with no parents") + self.fail("commit multiple parents") + + # re-add all files in lib self.fail( "add, commit, working tree handling" ) -- cgit v1.2.1 From 0725af77afc619cdfbe3cec727187e442cceaf97 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 26 Oct 2009 11:21:59 +0100 Subject: refs.SymoblicRef: implemented direcft setting of the symbolic references commit, which possibly dereferences to the respective head --- test/git/test_refs.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test') diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 696b95c7..979165ef 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -198,3 +198,21 @@ class TestRefs(TestBase): assert head.commit == old_commit # and the ref did not change head.object = head_tree assert head.object == head_tree + self.failUnlessRaises(TypeError, getattr, head, 'commit') # object is a tree, not a commit + + # set the commit directly using the head. This would never detach the head + assert not cur_head.is_detached + head.object = old_commit + cur_head.reference = head.commit + assert cur_head.is_detached + parent_commit = head.commit.parents[0] + assert cur_head.is_detached + cur_head.commit = parent_commit + assert cur_head.is_detached and cur_head.commit == parent_commit + + cur_head.reference = head + assert not cur_head.is_detached + cur_head.commit = parent_commit + assert not cur_head.is_detached + assert head.commit == parent_commit + -- cgit v1.2.1 From 5ba2aef8f59009756567a53daaf918afa851c304 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 26 Oct 2009 11:25:45 +0100 Subject: added head kwarg to reset and commit method, allowing to automatically change the head to the given commit, which makes the methods more versatile --- test/git/test_index.py | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index 0a5f4c35..e25f3d2e 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -191,6 +191,8 @@ class TestTree(TestBase): def test_index_mutation(self, rw_repo): index = rw_repo.index num_entries = len(index.entries) + cur_head = rw_repo.head + # remove all of the files, provide a wild mix of paths, BaseIndexEntries, # IndexEntries def mixed_iterator(): @@ -236,18 +238,39 @@ class TestTree(TestBase): assert len(deleted_files) > 1 self.failUnlessRaises(ValueError, index.remove, ["/doesnt/exists"]) - # test committing + # TEST COMMITTING # commit changed index - cur_commit = rw_repo.head.commit + cur_commit = cur_head.commit commit_message = "commit default head" - new_commit = index.commit(commit_message) + + new_commit = index.commit(commit_message, head=False) assert new_commit.message == commit_message assert new_commit.parents[0] == cur_commit - - self.fail("commit with no parents") - self.fail("commit multiple parents") - + assert len(new_commit.parents) == 1 + assert cur_head.commit == cur_commit + + # same index, no parents + commit_message = "index without parents" + commit_no_parents = index.commit(commit_message, parent_commits=list(), head=True) + assert commit_no_parents.message == commit_message + assert len(commit_no_parents.parents) == 0 + assert cur_head.commit == commit_no_parents + + # same index, multiple parents + commit_message = "Index with multiple parents\n commit with another line" + commit_multi_parent = index.commit(commit_message,parent_commits=(commit_no_parents, new_commit)) + assert commit_multi_parent.message == commit_message + assert len(commit_multi_parent.parents) == 2 + assert commit_multi_parent.parents[0] == commit_no_parents + assert commit_multi_parent.parents[1] == new_commit + assert cur_head.commit == commit_multi_parent # re-add all files in lib - self.fail( "add, commit, working tree handling" ) + # get the lib folder back on disk, but get an index without it + index.reset(new_commit.parents[0], working_tree=True).reset(new_commit, working_tree=False) + lib_file_path = "lib/git/__init__.py" + assert (lib_file_path, 0) not in index.entries + assert os.path.isfile(os.path.join(rw_repo.git.git_dir, lib_file_path)) + + self.fail( "add file using simple path, blob, blob as symlink, entries with stages" ) -- cgit v1.2.1 From 0ef1f89abe5b2334705ee8f1a6da231b0b6c9a50 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 26 Oct 2009 22:37:48 +0100 Subject: index.add: Finished implemenation including through tests index.checkout: added simple method allowing to checkout files from the index, including simple test --- test/git/test_index.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/git/test_index.py b/test/git/test_index.py index e25f3d2e..3312abe1 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -8,8 +8,10 @@ from test.testlib import * from git import * import inspect import os +import sys import tempfile import glob +from stat import * class TestTree(TestBase): @@ -174,6 +176,26 @@ class TestTree(TestBase): assert fp.read() != new_data finally: fp.close() + + # test full checkout + test_file = os.path.join(rw_repo.git.git_dir, "CHANGES") + os.remove(test_file) + index.checkout(None, force=True) + assert os.path.isfile(test_file) + + os.remove(test_file) + index.checkout(None, force=False) + assert os.path.isfile(test_file) + + # individual file + os.remove(test_file) + index.checkout(test_file) + assert os.path.exists(test_file) + + + + # currently it ignore non-existing paths + index.checkout(paths=["doesnt/exist"]) def _count_existing(self, repo, files): @@ -186,6 +208,17 @@ class TestTree(TestBase): # END num existing helper + def _make_file(self, rela_path, data, repo=None): + """ + Create a file at the given path relative to our repository, filled + with the given data. Returns absolute path to created file. + """ + repo = repo or self.rorepo + abs_path = os.path.join(repo.git.git_dir, rela_path) + fp = open(abs_path, "w") + fp.write(data) + fp.close() + return abs_path @with_rw_repo('0.1.6') def test_index_mutation(self, rw_repo): @@ -272,5 +305,51 @@ class TestTree(TestBase): assert (lib_file_path, 0) not in index.entries assert os.path.isfile(os.path.join(rw_repo.git.git_dir, lib_file_path)) - self.fail( "add file using simple path, blob, blob as symlink, entries with stages" ) + # directory + entries = index.add(['lib']) + assert len(entries)>1 + + # glob + entries = index.reset(new_commit).add(['lib/*.py']) + assert len(entries) == 14 + + # missing path + self.failUnlessRaises(GitCommandError, index.reset(new_commit).add, ['doesnt/exist/must/raise']) + + # blob from older revision overrides current index revision + old_blob = new_commit.parents[0].tree.blobs[0] + entries = index.reset(new_commit).add([old_blob]) + assert index.entries[(old_blob.path,0)].sha == old_blob.id and len(entries) == 1 + + # mode 0 not allowed + null_sha = "0"*40 + self.failUnlessRaises(ValueError, index.reset(new_commit).add, [BaseIndexEntry((0, null_sha,0,"doesntmatter"))]) + + # add new file + new_file_relapath = "my_new_file" + new_file_path = self._make_file(new_file_relapath, "hello world", rw_repo) + entries = index.reset(new_commit).add([BaseIndexEntry((010644, null_sha, 0, new_file_relapath))]) + assert len(entries) == 1 and entries[0].sha != null_sha + + # add symlink + if sys.platform != "win32": + link_file = os.path.join(rw_repo.git.git_dir, "my_real_symlink") + os.symlink("/etc/that", link_file) + entries = index.reset(new_commit).add([link_file]) + assert len(entries) == 1 and S_ISLNK(entries[0].mode) + print "%o" % entries[0].mode + # END real symlink test + + # add fake symlink and assure it checks-our as symlink + fake_symlink_relapath = "my_fake_symlink" + fake_symlink_path = self._make_file(fake_symlink_relapath, "/etc/that", rw_repo) + fake_entry = BaseIndexEntry((0120000, null_sha, 0, fake_symlink_relapath)) + entries = index.reset(new_commit).add([fake_entry]) + assert len(entries) == 1 and S_ISLNK(entries[0].mode) + + # checkout the fakelink, should be a link then + assert not S_ISLNK(os.stat(fake_symlink_path)[ST_MODE]) + os.remove(fake_symlink_path) + index.checkout(fake_symlink_path) + assert S_ISLNK(os.lstat(fake_symlink_path)[ST_MODE]) -- cgit v1.2.1