Browse Source

Support index writing.

Jelmer Vernooij 16 years ago
parent
commit
f93c222af8
2 changed files with 96 additions and 7 deletions
  1. 39 7
      dulwich/index.py
  2. 57 0
      dulwich/tests/test_index.py

+ 39 - 7
dulwich/index.py

@@ -23,6 +23,8 @@ import struct
 def read_cache_time(f):
     return struct.unpack(">LL", f.read(8))
 
+def write_cache_time(f, t):
+    f.write(struct.pack(">LL", *t))
 
 def read_cache_entry(f):
     beginoffset = f.tell()
@@ -40,25 +42,55 @@ def read_cache_entry(f):
     f.seek(beginoffset + real_size)
     return (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags)
 
+
+def write_cache_entry(f, entry):
+    beginoffset = f.tell()
+    (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags) = entry
+    write_cache_time(f, ctime)
+    write_cache_time(f, mtime)
+    f.write(struct.pack(">LLLLLL20sH", ino, dev, mode, uid, gid, size, sha, flags))
+    f.write(name)
+    f.write(chr(0))
+    real_size = ((f.tell() - beginoffset + 8) & ~7)
+    f.write(chr(0) * (f.tell() - (beginoffset + real_size)))
+    return 
+
+def read_index(f):
+    assert f.read(4) == "DIRC"
+    (version, num_entries) = struct.unpack(">LL", f.read(4 * 2))
+    assert version in (1, 2)
+    for i in range(num_entries):
+        yield read_cache_entry(f)
+
+
+def write_index(f, entries):
+    f.write("DIRC")
+    f.write(struct.pack(">LL", 2, len(entries)))
+    for x in entries:
+        write_cache_entry(f, x)
+
+
 class Index(object):
 
     def __init__(self, filename):
+        self._entries = []
         f = open(filename, 'r')
+        self._byname = {}
         try:
-            assert f.read(4) == "DIRC"
-            (version, self._num_entries) = struct.unpack(">LL", f.read(4 * 2))
-            assert version in (1, 2)
-            self._entries = []
-            for i in range(len(self)):
-                self._entries.append(read_cache_entry(f))
+            for x in read_index(f):
+                self._entries.append(x)
+                self._byname[x[0]] = x
         finally:
             f.close()
 
     def __len__(self):
-        return self._num_entries
+        return len(self._entries)
 
     def items(self):
         return list(self._entries)
 
     def __iter__(self):
         return iter(self._entries)
+
+    def __getitem__(self, name):
+        return self._byname[name]

+ 57 - 0
dulwich/tests/test_index.py

@@ -0,0 +1,57 @@
+# test_index.py -- Tests for the git index cache
+# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
+# 
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; version 2
+# of the License.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.
+
+from dulwich.index import Index, write_index
+import os
+from unittest import TestCase
+
+class IndexTestCase(TestCase):
+
+    datadir = os.path.join(os.path.dirname(__file__), 'data/indexes')
+
+    def get_simple_index(self, name):
+        return Index(os.path.join(self.datadir, name))
+
+
+class SimpleIndexTestcase(IndexTestCase):
+
+    def test_len(self):
+        self.assertEquals(1, len(self.get_simple_index("index")))
+
+    def test_iter(self):
+        self.assertEquals([
+            ('bla', (1230680220, 0), (1230680220, 0), 2050, 3761020, 33188, 1000, 1000, 0, '\xe6\x9d\xe2\x9b\xb2\xd1\xd6CK\x8b)\xaewZ\xd8\xc2\xe4\x8cS\x91', 3)
+            ], 
+                list(self.get_simple_index("index")))
+
+    def test_getitem(self):
+        self.assertEquals( ('bla', (1230680220, 0), (1230680220, 0), 2050, 3761020, 33188, 1000, 1000, 0, '\xe6\x9d\xe2\x9b\xb2\xd1\xd6CK\x8b)\xaewZ\xd8\xc2\xe4\x8cS\x91', 3)
+            , 
+                self.get_simple_index("index")["bla"])
+
+
+class SimpleIndexWriterTestCase(IndexTestCase):
+
+    def test_simple_write(self):
+        x = open('test-simple-write-index', 'w+')
+        try:
+            write_index(x, [('barbla', (1230680220, 0), (1230680220, 0), 2050, 3761020, 33188, 1000, 1000, 0, '\xe6\x9d\xe2\x9b\xb2\xd1\xd6CK\x8b)\xaewZ\xd8\xc2\xe4\x8cS\x91', 3)])
+        finally:
+            x.close()
+
+