Kaynağa Gözat

Fix skipping bug in index.

Jelmer Vernooij 16 yıl önce
ebeveyn
işleme
ac0afb6f5d
1 değiştirilmiş dosya ile 62 ekleme ve 9 silme
  1. 62 9
      dulwich/index.py

+ 62 - 9
dulwich/index.py

@@ -35,17 +35,23 @@ def read_cache_entry(f):
     (ino, dev, mode, uid, gid, size, sha, flags, ) = \
         struct.unpack(">LLLLLL20sH", f.read(20 + 4 * 6 + 2))
     name = ""
-    char = ord(f.read(1))
-    while char != 0:
-        name += chr(char)
-        char = ord(f.read(1))
+    char = f.read(1)
+    while char != "\0":
+        name += char
+        char = f.read(1)
     # Padding:
-    real_size = ((f.tell() - beginoffset + 8) & ~7)
+    real_size = ((f.tell() - beginoffset + 7) & ~7)
     f.seek(beginoffset + real_size)
     return (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags)
 
 
 def write_cache_entry(f, entry):
+    """Write an index entry to a file.
+
+    :param f: File object
+    :param entry: Entry to write, tuple with: 
+        (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags)
+    """
     beginoffset = f.tell()
     (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags) = entry
     write_cache_time(f, ctime)
@@ -58,30 +64,69 @@ def write_cache_entry(f, entry):
     return 
 
 def read_index(f):
-    assert f.read(4) == "DIRC"
+    """Read an index file, yielding the individual entries."""
+    header = f.read(4)
+    if header != "DIRC":
+        raise AssertionError("Invalid index file header: %r" % header)
     (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 read_index_dict(f):
+    """Read an index file and return it as a dictionary.
+    
+    :param f: File object to read from
+    """
+    ret = {}
+    for (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags) in read_index(f):
+        ret[name] = (ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags)
+    return ret
+
+
 def write_index(f, entries):
+    """Write an index file.
+    
+    :param f: File-like object to write to
+    :param entries: Iterable over the entries to write
+    """
     f.write("DIRC")
     f.write(struct.pack(">LL", 2, len(entries)))
     for x in entries:
         write_cache_entry(f, x)
 
 
+def write_index_dict(f, entries):
+    """Write an index file based on the contents of a dictionary.
+
+    """
+    entries_list = []
+    for name in sorted(entries):
+        entries_list.append((name,) + tuple(entries[name]))
+    write_index(f, entries_list)
+
+
 class Index(object):
 
     def __init__(self, filename):
         self._entries = []
-        f = open(filename, 'r')
+        self._filename = filename
         self._byname = {}
+        self.read()
+
+    def write(self):
+        f = open(self._filename, 'w')
+        try:
+            write_index(f, self._entries)
+        finally:
+            f.close()
+
+    def read(self):
+        f = open(self._filename, 'r')
         try:
             for x in read_index(f):
-                self._entries.append(x)
-                self._byname[x[0]] = x
+                self[x[0]] = x
         finally:
             f.close()
 
@@ -96,3 +141,11 @@ class Index(object):
 
     def __getitem__(self, name):
         return self._byname[name]
+
+    def __setitem__(self, name, x):
+        # Remove the old entry if any
+        old_entry = self._byname.get(x[0])
+        if old_entry is not None:
+            self._entries.remove(old_entry)
+        self._entries.append(x)
+        self._byname[x[0]] = x