diff options
-rw-r--r-- | lib/git/index.py | 30 | ||||
-rw-r--r-- | test/git/test_index.py | 15 |
2 files changed, 42 insertions, 3 deletions
diff --git a/lib/git/index.py b/lib/git/index.py index 45bf617f..bd9c73f1 100644 --- a/lib/git/index.py +++ b/lib/git/index.py @@ -160,6 +160,19 @@ class IndexEntry(BaseIndexEntry): return self[10] @classmethod + def from_base(cls, base): + """ + Returns + Minimal entry as created from the given BaseIndexEntry instance. + Missing values will be set to null-like values + + ``base`` + Instance of type BaseIndexEntry + """ + time = struct.pack(">LL", 0, 0) + return IndexEntry((base.mode, base.sha, base.stage, base.path, time, time, 1, 1, 1, 1, 0)) + + @classmethod def from_blob(cls, blob): """ Returns @@ -219,7 +232,8 @@ class IndexFile(LazyMixin, diff.Diffable): The index contains an entries dict whose keys are tuples of type IndexEntry to facilitate access. - You may only read the entries dict or manipulate it through designated methods. + You may read the entries dict or manipulate it using IndexEntry instance, i.e.:: + index.entries[index.get_entries_key(index_entry_instance)] = index_entry_instance Otherwise changes to it will be lost when changing the index using its methods. """ __slots__ = ( "repo", "version", "entries", "_extension_data", "_file_path" ) @@ -311,7 +325,7 @@ class IndexFile(LazyMixin, diff.Diffable): self.entries = dict() while count < num_entries: entry = self._read_entry(stream) - self.entries[(entry.path, entry.stage)] = entry + self.entries[self.get_entries_key(entry)] = entry count += 1 # END for each entry @@ -521,6 +535,18 @@ class IndexFile(LazyMixin, diff.Diffable): return path_map + @classmethod + def get_entries_key(cls, entry): + """ + Returns + Key suitable to be used for the index.entries dictionary + + ``entry`` + Instance of type BaseIndexEntry + """ + return (entry.path, entry.stage) + + def resolve_blobs(self, iter_blobs): """ Resolve the blobs given in blob iterator. This will effectively remove the diff --git a/test/git/test_index.py b/test/git/test_index.py index 1a543f82..a8ae4b8d 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -192,7 +192,8 @@ class TestTree(TestBase): index.checkout(test_file) assert os.path.exists(test_file) - + # checking out non-existing file is ignored/doesn't raise + index.checkout("doesnt_exist_ever.txt.that") # currently it ignore non-existing paths index.checkout(paths=["doesnt/exist"]) @@ -336,8 +337,20 @@ class TestTree(TestBase): fake_symlink_path = self._make_file(fake_symlink_relapath, link_target, rw_repo) fake_entry = BaseIndexEntry((0120000, null_sha, 0, fake_symlink_relapath)) entries = index.reset(new_commit).add([fake_entry]) + assert entries[0].sha != null_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].sha, 0, entries[0].path))) + entry_key = index.get_entries_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) + # checkout the fakelink, should be a link then assert not S_ISLNK(os.stat(fake_symlink_path)[ST_MODE]) os.remove(fake_symlink_path) |