summaryrefslogtreecommitdiff
path: root/lib/git/index
diff options
context:
space:
mode:
Diffstat (limited to 'lib/git/index')
-rw-r--r--lib/git/index/base.py12
-rw-r--r--lib/git/index/fun.py69
2 files changed, 40 insertions, 41 deletions
diff --git a/lib/git/index/base.py b/lib/git/index/base.py
index 05501ba1..05caa06d 100644
--- a/lib/git/index/base.py
+++ b/lib/git/index/base.py
@@ -35,7 +35,8 @@ from git.exc import (
)
from git.objects import (
- Blob,
+ Blob,
+ Submodule,
Tree,
Object,
Commit,
@@ -553,7 +554,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
for item in items:
if isinstance(item, basestring):
paths.append(self._to_relative_path(item))
- elif isinstance(item, Blob):
+ elif isinstance(item, (Blob, Submodule)):
entries.append(BaseIndexEntry.from_blob(item))
elif isinstance(item, BaseIndexEntry):
entries.append(item)
@@ -588,7 +589,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
They are added at stage 0
- - Blob object
+ - Blob or Submodule object
Blobs are added as they are assuming a valid mode is set.
The file they refer to may or may not exist in the file system, but
must be a path relative to our repository.
@@ -612,6 +613,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
explicitly set. Please note that Index Entries require binary sha's.
:param force:
+ **CURRENTLY INEFFECTIVE**
If True, otherwise ignored or excluded files will be
added anyway.
As opposed to the git-add command, we enable this flag by default
@@ -748,7 +750,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
may be absolute or relative paths, entries or blobs"""
paths = list()
for item in items:
- if isinstance(item, (BaseIndexEntry,Blob)):
+ if isinstance(item, (BaseIndexEntry,(Blob, Submodule))):
paths.append(self._to_relative_path(item.path))
elif isinstance(item, basestring):
paths.append(self._to_relative_path(item))
@@ -775,7 +777,7 @@ class IndexFile(LazyMixin, diff.Diffable, Serializable):
The path string may include globs, such as *.c.
- - Blob object
+ - Blob Object
Only the path portion is used in this case.
- BaseIndexEntry or compatible type
diff --git a/lib/git/index/fun.py b/lib/git/index/fun.py
index 48c4fa74..87fdf1a9 100644
--- a/lib/git/index/fun.py
+++ b/lib/git/index/fun.py
@@ -30,6 +30,7 @@ from typ import (
CE_NAMEMASK,
CE_STAGESHIFT
)
+CE_NAMEMASK_INV = ~CE_NAMEMASK
from util import (
pack,
@@ -53,22 +54,6 @@ def stat_mode_to_index_mode(mode):
return S_IFREG | 0644 | (mode & 0100) # blobs with or without executable bit
-def write_cache_entry(entry, stream):
- """Write the given entry to the stream"""
- beginoffset = stream.tell()
- write = stream.write
- write(entry[4]) # ctime
- write(entry[5]) # mtime
- path = entry[3]
- plen = len(path) & CE_NAMEMASK # path length
- assert plen == len(path), "Path %s too long to fit into index" % entry[3]
- flags = plen | entry[2]
- write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0],
- entry[8], entry[9], entry[10], entry[1], flags))
- write(path)
- real_size = ((stream.tell() - beginoffset + 8) & ~7)
- write("\0" * ((beginoffset + real_size) - stream.tell()))
-
def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1Writer):
"""Write the cache represented by entries to a stream
@@ -83,15 +68,29 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1
a 4 byte identifier, followed by its size ( 4 bytes )"""
# wrap the stream into a compatible writer
stream = ShaStreamCls(stream)
+
+ tell = stream.tell
+ write = stream.write
# header
version = 2
- stream.write("DIRC")
- stream.write(pack(">LL", version, len(entries)))
+ write("DIRC")
+ write(pack(">LL", version, len(entries)))
# body
for entry in entries:
- write_cache_entry(entry, stream)
+ beginoffset = tell()
+ write(entry[4]) # ctime
+ write(entry[5]) # mtime
+ path = entry[3]
+ plen = len(path) & CE_NAMEMASK # path length
+ assert plen == len(path), "Path %s too long to fit into index" % entry[3]
+ flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values
+ write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0],
+ entry[8], entry[9], entry[10], entry[1], flags))
+ write(path)
+ real_size = ((tell() - beginoffset + 8) & ~7)
+ write("\0" * ((beginoffset + real_size) - tell()))
# END for each entry
# write previously cached extensions data
@@ -101,21 +100,6 @@ def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1
# write the sha over the content
stream.write_sha()
-def read_entry(stream):
- """Return: One entry of the given stream"""
- beginoffset = stream.tell()
- read = stream.read
- ctime = unpack(">8s", read(8))[0]
- mtime = unpack(">8s", read(8))[0]
- (dev, ino, mode, uid, gid, size, sha, flags) = \
- unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
- path_size = flags & CE_NAMEMASK
- path = read(path_size)
-
- real_size = ((stream.tell() - beginoffset + 8) & ~7)
- data = read((beginoffset + real_size) - stream.tell())
- return IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
-
def read_header(stream):
"""Return tuple(version_long, num_entries) from the given stream"""
type_id = stream.read(4)
@@ -147,10 +131,23 @@ def read_cache(stream):
version, num_entries = read_header(stream)
count = 0
entries = dict()
+
+ read = stream.read
+ tell = stream.tell
while count < num_entries:
- entry = read_entry(stream)
+ beginoffset = tell()
+ ctime = unpack(">8s", read(8))[0]
+ mtime = unpack(">8s", read(8))[0]
+ (dev, ino, mode, uid, gid, size, sha, flags) = \
+ unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
+ path_size = flags & CE_NAMEMASK
+ path = read(path_size)
+
+ real_size = ((tell() - beginoffset + 8) & ~7)
+ data = read((beginoffset + real_size) - tell())
+ entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
# entry_key would be the method to use, but we safe the effort
- entries[(entry.path, entry.stage)] = entry
+ entries[(path, entry.stage)] = entry
count += 1
# END for each entry