diff options
Diffstat (limited to 'git/test/test_index.py')
| -rw-r--r-- | git/test/test_index.py | 218 | 
1 files changed, 108 insertions, 110 deletions
| diff --git a/git/test/test_index.py b/git/test/test_index.py index d532a3b4..9d75da53 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -15,11 +15,11 @@ import shutil  from stat import *  class TestIndex(TestBase): -     +      def __init__(self, *args):          super(TestIndex, self).__init__(*args)          self._reset_progress() -     +      def _assert_fprogress(self, entries):          assert len(entries) == len(self._fprogress_map)          for path, call_count in self._fprogress_map.iteritems(): @@ -35,30 +35,30 @@ class TestIndex(TestBase):          if curval == 1:              assert done          self._fprogress_map[path] = curval + 1 -         +      def _fprogress_add(self, path, done, item):          """Called as progress func - we keep track of the proper           call order"""          assert item is not None          self._fprogress(path, done, item) -         +      def _reset_progress(self):          # maps paths to the count of calls          self._fprogress_map = dict() -         +      def _assert_entries(self, entries):          for entry in entries:              assert isinstance(entry, BaseIndexEntry)              assert not os.path.isabs(entry.path)              assert not "\\" in entry.path          # END for each entry -     +      def test_index_file_base(self):          # read from file          index = IndexFile(self.rorepo, fixture_path("index"))          assert index.entries          assert index.version > 0 -         +          # test entry          last_val = None          entry = index.entries.itervalues().next() @@ -66,17 +66,17 @@ class TestIndex(TestBase):                                  "gid","size","binsha", "hexsha", "stage"):              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          assert len(list(e for e in index_merge.entries.itervalues() if e.stage != 0 )) -         +          # write the data - it must match the original          tmpfile = tempfile.mktemp()          index_merge.write(tmpfile) @@ -84,12 +84,12 @@ class TestIndex(TestBase):          assert fp.read() == fixture("index_merge")          fp.close()          os.remove(tmpfile) -     +      def _cmp_tree_index(self, tree, index):          # fail unless both objects contain the same paths and blobs          if isinstance(tree, str):              tree = self.rorepo.commit(tree).tree -         +          num_blobs = 0          blist = list()          for blob in tree.traverse(predicate = lambda e,d: e.type == "blob", branch_first=False): @@ -101,48 +101,48 @@ class TestIndex(TestBase):              bset = set(b.path for b in blist)              raise AssertionError( "CMP Failed: Missing entries in index: %s, missing in tree: %s" % (bset-iset, iset-bset) )          # END assertion message -     +      @with_rw_repo('0.1.6')      def test_index_file_from_tree(self, rw_repo):          common_ancestor_sha = "5117c9c8a4d3af19a9958677e45cda9269de1541"          cur_sha = "4b43ca7ff72d5f535134241e7c797ddc9c7a3573"          other_sha = "39f85c4358b7346fee22169da9cad93901ea9eb9" -         +          # simple index from tree           base_index = IndexFile.from_tree(rw_repo, 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 = IndexFile.from_tree(rw_repo, 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 = IndexFile.from_tree(rw_repo, common_ancestor_sha, cur_sha, other_sha)          assert len(list(e for e in three_way_index.entries.values() if e.stage != 0)) -         -         + +          # ITERATE BLOBS          merge_required = lambda t: t[0] != 0          merge_blobs = list(three_way_index.iter_blobs(merge_required))          assert merge_blobs          assert merge_blobs[0][0] in (1,2,3)          assert isinstance(merge_blobs[0][1], Blob) -         +          # test BlobFilter          prefix = 'lib/git'          for stage, blob in base_index.iter_blobs(BlobFilter([prefix])):              assert blob.path.startswith(prefix)  -         -         + +          # writing a tree should fail with an unmerged index          self.failUnlessRaises(UnmergedEntriesError, three_way_index.write_tree) -         +          # removed unmerged entries          unmerged_blob_map = three_way_index.unmerged_blobs()          assert unmerged_blob_map -         +          # pick the first blob at the first stage we find and use it as resolved version          three_way_index.resolve_blobs( l[0][1] for l in unmerged_blob_map.itervalues() )          tree = three_way_index.write_tree() @@ -153,13 +153,13 @@ class TestIndex(TestBase):              num_blobs += 1          # END for each blob          assert num_blobs == len(three_way_index.entries) -     +      @with_rw_repo('0.1.6')      def test_index_merge_tree(self, rw_repo):          # A bit out of place, but we need a different repo for this:           assert self.rorepo != rw_repo and not (self.rorepo == rw_repo)          assert len(set((self.rorepo, self.rorepo, rw_repo, rw_repo))) == 2 -         +          # SINGLE TREE MERGE          # current index is at the (virtual) cur_commit          next_commit = "4c39f9da792792d4e73fc3a5effde66576ae128c" @@ -169,10 +169,10 @@ class TestIndex(TestBase):          rw_repo.index.merge_tree(next_commit)          # only one change should be recorded          assert manifest_entry.binsha != rw_repo.index.entries[manifest_key].binsha -         +          rw_repo.index.reset(rw_repo.head)          assert rw_repo.index.entries[manifest_key].binsha == manifest_entry.binsha -         +          # FAKE MERGE          #############          # Add a change with a NULL sha that should conflict with next_commit. We  @@ -190,86 +190,86 @@ class TestIndex(TestBase):          index.entries[manifest_key] = IndexEntry.from_base(manifest_fake_entry)          index.write()          assert rw_repo.index.entries[manifest_key].hexsha == Diff.NULL_HEX_SHA -         +          # write an unchanged index ( just for the fun of it )          rw_repo.index.write() -         +          # a three way merge would result in a conflict and fails as the command will           # not overwrite any entries in our index and hence leave them unmerged. This is           # mainly a protection feature as the current index is not yet in a tree          self.failUnlessRaises(GitCommandError, index.merge_tree, next_commit, base=parent_commit) -         +          # the only way to get the merged entries is to safe the current index away into a tree,           # which is like a temporary commit for us. This fails as well as the NULL sha deos not          # have a corresponding object          # NOTE: missing_ok is not a kwarg anymore, missing_ok is always true          # self.failUnlessRaises(GitCommandError, index.write_tree) -         +          # if missing objects are okay, this would work though ( they are always okay now )          tree = index.write_tree() -         +          # now make a proper three way merge with unmerged entries          unmerged_tree = IndexFile.from_tree(rw_repo, parent_commit, tree, next_commit)          unmerged_blobs = unmerged_tree.unmerged_blobs()          assert len(unmerged_blobs) == 1 and unmerged_blobs.keys()[0] == manifest_key[0] -         -     + +      @with_rw_repo('0.1.6')      def test_index_file_diffing(self, rw_repo):          # default Index instance points to our index          index = IndexFile(rw_repo)          assert index.path is not None          assert len(index.entries) -         +          # write the file back          index.write() -         +          # could sha it, or check stats -         +          # test diff          # resetting the head will leave the index in a different state, and the           # diff will yield a few changes          cur_head_commit = rw_repo.head.reference.commit          ref = rw_repo.head.reset('HEAD~6', index=True, working_tree=False) -         +          # diff against same index is 0          diff = index.diff()          assert len(diff) == 0 -         +          # against HEAD as string, must be the same as it matches index          diff = index.diff('HEAD')          assert len(diff) == 0 -         +          # against previous head, there must be a difference          diff = index.diff(cur_head_commit)          assert len(diff) -         +          # we reverse the result          adiff = index.diff(str(cur_head_commit), R=True)          odiff = index.diff(cur_head_commit, R=False)    # now its not reversed anymore          assert adiff != odiff          assert odiff == diff                    # both unreversed diffs against HEAD -         +          # against working copy - its still at cur_commit          wdiff = index.diff(None)          assert wdiff != adiff          assert wdiff != odiff -         +          # against something unusual          self.failUnlessRaises(ValueError, index.diff, int) -         +          # 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.working_tree_dir, "CHANGES") @@ -285,7 +285,7 @@ class TestIndex(TestBase):              assert fp.read() != new_data          finally:              fp.close() -             +          # test full checkout          test_file = os.path.join(rw_repo.working_tree_dir, "CHANGES")          open(test_file, 'ab').write("some data") @@ -293,24 +293,24 @@ class TestIndex(TestBase):          assert 'CHANGES' in list(rval)          self._assert_fprogress([None])          assert os.path.isfile(test_file) -         +          os.remove(test_file)          rval = index.checkout(None, force=False, fprogress=self._fprogress)          assert 'CHANGES' in list(rval)          self._assert_fprogress([None])          assert os.path.isfile(test_file) -         +          # individual file          os.remove(test_file)          rval = index.checkout(test_file, fprogress=self._fprogress)          assert list(rval)[0] == 'CHANGES'          self._assert_fprogress([test_file])          assert os.path.exists(test_file) -         +          # checking out non-existing file throws          self.failUnlessRaises(CheckoutError, index.checkout, "doesnt_exist_ever.txt.that")          self.failUnlessRaises(CheckoutError, index.checkout, paths=["doesnt/exist"]) -         +          # checkout file with modifications          append_data = "hello"          fp = open(test_file, "ab") @@ -325,16 +325,16 @@ class TestIndex(TestBase):              assert open(test_file).read().endswith(append_data)          else:              raise AssertionError("Exception CheckoutError not thrown") -     +          # if we force it it should work          index.checkout(test_file, force=True)          assert not open(test_file).read().endswith(append_data) -         +          # checkout directory          shutil.rmtree(os.path.join(rw_repo.working_tree_dir, "lib"))          rval = index.checkout('lib')          assert len(list(rval)) > 1 -     +      def _count_existing(self, repo, files):          """          Returns count of files that actually exist in the repository directory. @@ -346,18 +346,18 @@ class TestIndex(TestBase):          # END for each deleted file          return existing      # END num existing helper -     +      @with_rw_repo('0.1.6')      def test_index_mutation(self, rw_repo):          index = rw_repo.index          num_entries = len(index.entries)          cur_head = rw_repo.head -         +          uname = "Some Developer"          umail = "sd@company.com"          rw_repo.config_writer().set_value("user", "name", uname)          rw_repo.config_writer().set_value("user", "email", umail)  -         +          # remove all of the files, provide a wild mix of paths, BaseIndexEntries,           # IndexEntries          def mixed_iterator(): @@ -381,33 +381,33 @@ class TestIndex(TestBase):          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.working_tree_dir,"lib")], r=True)          assert len(deleted_files) > 1          self.failUnlessRaises(ValueError, index.remove, ["/doesnt/exists"]) -         +          # TEST COMMITTING          # commit changed index          cur_commit = cur_head.commit          commit_message = "commit default head" -         +          new_commit = index.commit(commit_message, head=False)          assert cur_commit != new_commit          assert new_commit.author.name == uname @@ -418,14 +418,14 @@ class TestIndex(TestBase):          assert new_commit.parents[0] == cur_commit          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)) @@ -434,26 +434,26 @@ class TestIndex(TestBase):          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          # 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 = os.path.join("lib", "git", "__init__.py")          assert (lib_file_path, 0) not in index.entries          assert os.path.isfile(os.path.join(rw_repo.working_tree_dir, lib_file_path)) -         +          # directory          entries = index.add(['lib'], fprogress=self._fprogress_add)          self._assert_entries(entries)          self._assert_fprogress(entries) -        assert len(entries)>1 -         +        assert len(entries) > 1 +          # glob           entries = index.reset(new_commit).add([os.path.join('lib', 'git', '*.py')], fprogress=self._fprogress_add)          self._assert_entries(entries)          self._assert_fprogress(entries)          assert len(entries) == 14 -         +          # same file           entries = index.reset(new_commit).add([os.path.abspath(os.path.join('lib', 'git', 'head.py'))]*2, fprogress=self._fprogress_add)          self._assert_entries(entries) @@ -462,22 +462,22 @@ class TestIndex(TestBase):          # self._assert_fprogress(entries)          self._reset_progress()          assert len(entries) == 2 -         +          # missing path          self.failUnlessRaises(OSError, 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], fprogress=self._fprogress_add)          self._assert_entries(entries)          self._assert_fprogress(entries)          assert index.entries[(old_blob.path,0)].hexsha == old_blob.hexsha and len(entries) == 1  -         +          # mode 0 not allowed          null_hex_sha = Diff.NULL_HEX_SHA          null_bin_sha = "\0" * 20          self.failUnlessRaises(ValueError, index.reset(new_commit).add, [BaseIndexEntry((0, null_bin_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) @@ -485,7 +485,7 @@ class TestIndex(TestBase):          self._assert_entries(entries)          self._assert_fprogress(entries)          assert len(entries) == 1 and entries[0].hexsha != null_hex_sha -         +          # add symlink          if sys.platform != "win32":              basename = "my_real_symlink" @@ -497,11 +497,11 @@ class TestIndex(TestBase):              self._assert_fprogress(entries)              assert len(entries) == 1 and S_ISLNK(entries[0].mode)              assert S_ISLNK(index.entries[index.entry_key("my_real_symlink", 0)].mode) -             +              # we expect only the target to be written              assert index.repo.odb.stream(entries[0].binsha).read() == target          # END real symlink test  -         +          # add fake symlink and assure it checks-our as symlink          fake_symlink_relapath = "my_fake_symlink"          link_target = "/etc/that" @@ -512,29 +512,29 @@ class TestIndex(TestBase):          self._assert_fprogress(entries)          assert entries[0].hexsha != null_hex_sha          assert len(entries) == 1 and S_ISLNK(entries[0].mode) -         +          # assure this also works with an alternate method          full_index_entry = IndexEntry.from_base(BaseIndexEntry((0120000, entries[0].binsha, 0, entries[0].path)))          entry_key = index.entry_key(full_index_entry)          index.reset(new_commit) -         +          assert entry_key not in index.entries          index.entries[entry_key] = full_index_entry          index.write()          index.update()  # force reread of entries          new_entry = index.entries[entry_key]          assert S_ISLNK(new_entry.mode) -         +          # a tree created from this should contain the symlink          tree = index.write_tree()          assert fake_symlink_relapath in tree          index.write()                       # flush our changes for the checkout -         +          # 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) -         +          # on windows we will never get symlinks          if os.name == 'nt':              # simlinks should contain the link as text ( which is what a  @@ -542,37 +542,37 @@ class TestIndex(TestBase):              open(fake_symlink_path,'rb').read() == link_target           else:              assert S_ISLNK(os.lstat(fake_symlink_path)[ST_MODE]) -             +          # TEST RENAMING          def assert_mv_rval(rval):              for source, dest in rval:                  assert not os.path.exists(source) and os.path.exists(dest)              # END for each renamed item          # END move assertion utility -         +          self.failUnlessRaises(ValueError, index.move, ['just_one_path'])          # file onto existing file          files = ['AUTHORS', 'LICENSE']          self.failUnlessRaises(GitCommandError, index.move, files) -         +          # again, with force           assert_mv_rval(index.move(files, f=True)) -         +          # files into directory - dry run          paths = ['LICENSE', 'VERSION', 'doc']          rval = index.move(paths, dry_run=True)          assert len(rval) == 2          assert os.path.exists(paths[0]) -         +          # again, no dry run          rval = index.move(paths)          assert_mv_rval(rval) -         +          # dir into dir          rval = index.move(['doc', 'test'])          assert_mv_rval(rval) -         -         + +          # TEST PATH REWRITING          ######################          count = [0] @@ -581,14 +581,14 @@ class TestIndex(TestBase):              count[0] += 1              return rval          # END rewriter -         +          def make_paths():              # two existing ones, one new one              yield 'CHANGES'              yield 'ez_setup.py'              yield index.entries[index.entry_key('README', 0)]              yield index.entries[index.entry_key('.gitignore', 0)] -             +              for fid in range(3):                  fname = 'newfile%i' % fid                  open(fname, 'wb').write("abcd") @@ -597,11 +597,11 @@ class TestIndex(TestBase):          # END path producer          paths = list(make_paths())          self._assert_entries(index.add(paths, path_rewriter=rewriter)) -         +          for filenum in range(len(paths)):              assert index.entry_key(str(filenum), 0) in index.entries -             -             + +          # TEST RESET ON PATHS          ######################          arela = "aa" @@ -613,34 +613,34 @@ class TestIndex(TestBase):          keys = (akey, bkey)          absfiles = (afile, bfile)          files = (arela, brela) -         +          for fkey in keys:              assert not fkey in index.entries -         +          index.add(files, write=True)          nc = index.commit("2 files committed", head=False) -         +          for fkey in keys:              assert fkey in index.entries -         +          # just the index          index.reset(paths=(arela, afile))          assert not akey in index.entries          assert bkey in index.entries -         +          # now with working tree - files on disk as well as entries must be recreated          rw_repo.head.commit = nc          for absfile in absfiles:              os.remove(absfile) -         +          index.reset(working_tree=True, paths=files) -         +          for fkey in keys:               assert fkey in index.entries          for absfile in absfiles:              assert os.path.isfile(absfile) -                 -         + +      @with_rw_repo('HEAD')      def test_compare_write_tree(self, rw_repo):          # write all trees and compare them @@ -655,15 +655,13 @@ class TestIndex(TestBase):              orig_tree = commit.tree              assert index.write_tree() == orig_tree          # END for each commit  -         +      def test_index_new(self):          B = self.rorepo.tree("6d9b1f4f9fa8c9f030e3207e7deacc5d5f8bba4e")          H = self.rorepo.tree("25dca42bac17d511b7e2ebdd9d1d679e7626db5f")          M = self.rorepo.tree("e746f96bcc29238b79118123028ca170adc4ff0f") -         +          for args in ((B,), (B,H), (B,H,M)):              index = IndexFile.new(self.rorepo, *args)              assert isinstance(index, IndexFile)          # END for each arg tuple -         -         | 
