summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/git/index.py30
-rw-r--r--test/git/test_index.py15
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)