diff options
Diffstat (limited to 'lib/git')
-rw-r--r-- | lib/git/index.py | 22 | ||||
-rw-r--r-- | lib/git/utils.py | 52 |
2 files changed, 71 insertions, 3 deletions
diff --git a/lib/git/index.py b/lib/git/index.py index d8ba6e18..9a55da15 100644 --- a/lib/git/index.py +++ b/lib/git/index.py @@ -15,6 +15,7 @@ import tempfile import os import stat from git.objects import Blob, Tree +from git.utils import SHA1Writer class _TemporaryFileSwap(object): """ @@ -205,11 +206,20 @@ class Index(object): count = 0 while count < num_entries: entry = self._read_entry(stream) - self.entries[(entry.path,entry.stage)] = entry + self.entries[(entry.path, entry.stage)] = entry count += 1 # END for each entry - # this data chunk is the footer of the index, don't yet know what it is for + + # the footer contains extension data and a sha on the content so far + # Keep the extension footer,and verify we have a sha in the end self._extension_data = stream.read(~0) + assert len(self._extension_data) > 19, "Index Footer was not at least a sha on content as it was only %i bytes in size" % len(self._extension_data) + + content_sha = self._extension_data[-20:] + + # truncate the sha in the end as we will dynamically create it anyway + self._extension_data = self._extension_data[:-20] + @classmethod def from_file(cls, repo, file_path): @@ -296,6 +306,8 @@ class Index(object): Note Index writing based on the dulwich implementation """ + stream = SHA1Writer(stream) + # header stream.write("DIRC") stream.write(struct.pack(">LL", self.version, len(self.entries))) @@ -306,9 +318,13 @@ class Index(object): for entry in entries_sorted: self._write_cache_entry(stream, entry) # END for each entry - # write extension_data which we currently cannot interprete + + # write previously cached extensions data stream.write(self._extension_data) + # write the sha over the content + stream.write_sha() + @classmethod def from_tree(cls, repo, *treeish, **kwargs): diff --git a/lib/git/utils.py b/lib/git/utils.py index 2aa8d33e..cdc7c55b 100644 --- a/lib/git/utils.py +++ b/lib/git/utils.py @@ -6,6 +6,58 @@ import os +try: + import hashlib +except ImportError: + import sha + +def make_sha(source=''): + """ + A python2.4 workaround for the sha/hashlib module fiasco + + Note + From the dulwich project + """ + try: + return hashlib.sha1(source) + except NameError: + sha1 = sha.sha(source) + return sha1 + + +class SHA1Writer(object): + """ + Wrapper around a file-like object that remembers the SHA1 of + the data written to it. It will write a sha when the stream is closed + or if the asked for explicitly usign write_sha. + + Note: + Based on the dulwich project + """ + __slots__ = ("f", "sha1") + + def __init__(self, f): + self.f = f + self.sha1 = make_sha("") + + def write(self, data): + self.sha1.update(data) + self.f.write(data) + + def write_sha(self): + sha = self.sha1.digest() + self.f.write(sha) + return sha + + def close(self): + sha = self.write_sha() + self.f.close() + return sha + + def tell(self): + return self.f.tell() + + class LazyMixin(object): """ Base class providing an interface to lazily retrieve attribute values upon |